线段树。
父亲节点的改变,需要让儿子节点继承父亲节点原来的状态,而儿子节点的改变也可以更新父亲节点的信息。
Hotel
http://acm.pku.edu.cn/JudgeOnline/problem?id=1823
http://acm.pku.edu.cn/JudgeOnline/problem?id=2828
Buy Tickets
http://acm.pku.edu.cn/JudgeOnline/problem?id=3277
City Horizon
http://acm.pku.edu.cn/JudgeOnline/problem?id=3368
Frequent Values
父亲节点的改变,需要让儿子节点继承父亲节点原来的状态,而儿子节点的改变也可以更新父亲节点的信息。
Hotel
http://acm.pku.edu.cn/JudgeOnline/problem?id=1823
POJ 1823
//flag1=1表示没人,flag0=0表示人满
//每个节点记录左端点,右端点,左端点开始连续free的最大值lmax,右端点开始连续free的最大值rmax,节点的连续free的最大值ma,以及两个flag
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct node
{
int l,r;
int lmax,rmax,ma;
bool flag1,flag0;//flag1表示没人,flag0表示有人
}T[160001];
int build(int s,int e,int u)
{
T[u].l=s;
T[u].r=e;
T[u].flag0=0;//非满
T[u].flag1=1;//全空
T[u].lmax=T[u].rmax=T[u].ma=e-s+1;
if(s<e)
{
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid+1,e,2*u+1);
}
return 0;
}
int checkin(int s,int e,int u)//住人
{
if(T[u].flag1)
{
T[u].flag1=0;//非空
T[2*u].flag1=1;
T[2*u].flag0=0;
T[2*u].lmax=T[2*u].rmax=T[2*u].ma=(T[2*u].r-T[2*u].l+1);
T[2*u+1].flag1=1;
T[2*u+1].flag0=0;
T[2*u+1].lmax=T[2*u+1].rmax=T[2*u+1].ma=(T[2*u+1].r-T[2*u+1].l+1);
}
if(s<=T[u].l&&e>=T[u].r)
{
T[u].flag0=1;//住满
T[u].lmax=T[u].rmax=T[u].ma=0;
return 0;
}
if(s<=T[2*u].r)
{
checkin(s,e,2*u);
}
if(e>=T[2*u+1].l)
{
checkin(s,e,2*u+1);
}
T[u].ma=max(T[2*u].ma,T[2*u+1].ma);
T[u].ma=max(T[u].ma,T[2*u].rmax+T[2*u+1].lmax);
if(T[2*u].lmax==T[2*u].r-T[2*u].l+1)
{
T[u].lmax=T[2*u].lmax+T[2*u+1].lmax;
}
else
T[u].lmax=T[2*u].lmax;
if(T[2*u+1].rmax==T[2*u+1].r-T[2*u+1].l+1)
{
T[u].rmax=T[2*u].rmax+T[2*u+1].ma;
}
else
T[u].rmax=T[2*u+1].rmax;
if(T[u].ma==0)
T[u].flag0=1;//住满
return 0;
}
int checkout(int s,int e,int u)//走人
{
if(T[u].flag0)//住满
{
T[u].flag0=0;//非满
T[2*u].flag0=1;
T[2*u].flag1=0;
T[2*u].lmax=T[2*u].rmax=T[2*u].ma=0;
T[2*u+1].flag0=1;
T[2*u+1].flag1=0;
T[2*u+1].lmax=T[2*u+1].rmax=T[2*u+1].ma=0;
}
if(s<=T[u].l&&e>=T[u].r)
{
T[u].flag1=1;//全走,为空
T[u].lmax=T[u].rmax=T[u].ma=T[u].r-T[u].l+1;
return 0;
}
if(s<=T[2*u].r)
checkout(s,e,2*u);
if(e>=T[2*u+1].l)
checkout(s,e,2*u+1);
T[u].ma=max(T[2*u].ma,T[2*u+1].ma);
T[u].ma=max(T[u].ma,T[2*u].rmax+T[2*u+1].lmax);
if(T[2*u].lmax==T[2*u].r-T[2*u].l+1)
{
T[u].lmax=T[2*u].lmax+T[2*u+1].lmax;
}
else
T[u].lmax=T[2*u].lmax;
if(T[2*u+1].rmax==T[2*u+1].r-T[2*u+1].l+1)
{
T[u].rmax=T[2*u].rmax+T[2*u+1].rmax;
}
else
T[u].rmax=T[2*u+1].rmax;
if(T[u].ma==T[u].r-T[u].l+1)
T[u].flag1=1;
return 0;
}
int n,k;
int a,b,c;
int main()
{
scanf("%d%d",&n,&k);
build(1,n,1);
int i,j;
for(i=1;i<=k;i++)
{
scanf("%d",&c);
if(c==1)
{
scanf("%d%d",&a,&b);
checkin(a,a+b-1,1);
}
else if(c==2)
{
scanf("%d%d",&a,&b);
checkout(a,a+b-1,1);
}
else
printf("%d\n",T[1].ma);
}
system("pause");
return 0;
}
//flag1=1表示没人,flag0=0表示人满
//每个节点记录左端点,右端点,左端点开始连续free的最大值lmax,右端点开始连续free的最大值rmax,节点的连续free的最大值ma,以及两个flag
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct node
{
int l,r;
int lmax,rmax,ma;
bool flag1,flag0;//flag1表示没人,flag0表示有人
}T[160001];
int build(int s,int e,int u)
{
T[u].l=s;
T[u].r=e;
T[u].flag0=0;//非满
T[u].flag1=1;//全空
T[u].lmax=T[u].rmax=T[u].ma=e-s+1;
if(s<e)
{
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid+1,e,2*u+1);
}
return 0;
}
int checkin(int s,int e,int u)//住人
{
if(T[u].flag1)
{
T[u].flag1=0;//非空
T[2*u].flag1=1;
T[2*u].flag0=0;
T[2*u].lmax=T[2*u].rmax=T[2*u].ma=(T[2*u].r-T[2*u].l+1);
T[2*u+1].flag1=1;
T[2*u+1].flag0=0;
T[2*u+1].lmax=T[2*u+1].rmax=T[2*u+1].ma=(T[2*u+1].r-T[2*u+1].l+1);
}
if(s<=T[u].l&&e>=T[u].r)
{
T[u].flag0=1;//住满
T[u].lmax=T[u].rmax=T[u].ma=0;
return 0;
}
if(s<=T[2*u].r)
{
checkin(s,e,2*u);
}
if(e>=T[2*u+1].l)
{
checkin(s,e,2*u+1);
}
T[u].ma=max(T[2*u].ma,T[2*u+1].ma);
T[u].ma=max(T[u].ma,T[2*u].rmax+T[2*u+1].lmax);
if(T[2*u].lmax==T[2*u].r-T[2*u].l+1)
{
T[u].lmax=T[2*u].lmax+T[2*u+1].lmax;
}
else
T[u].lmax=T[2*u].lmax;
if(T[2*u+1].rmax==T[2*u+1].r-T[2*u+1].l+1)
{
T[u].rmax=T[2*u].rmax+T[2*u+1].ma;
}
else
T[u].rmax=T[2*u+1].rmax;
if(T[u].ma==0)
T[u].flag0=1;//住满
return 0;
}
int checkout(int s,int e,int u)//走人
{
if(T[u].flag0)//住满
{
T[u].flag0=0;//非满
T[2*u].flag0=1;
T[2*u].flag1=0;
T[2*u].lmax=T[2*u].rmax=T[2*u].ma=0;
T[2*u+1].flag0=1;
T[2*u+1].flag1=0;
T[2*u+1].lmax=T[2*u+1].rmax=T[2*u+1].ma=0;
}
if(s<=T[u].l&&e>=T[u].r)
{
T[u].flag1=1;//全走,为空
T[u].lmax=T[u].rmax=T[u].ma=T[u].r-T[u].l+1;
return 0;
}
if(s<=T[2*u].r)
checkout(s,e,2*u);
if(e>=T[2*u+1].l)
checkout(s,e,2*u+1);
T[u].ma=max(T[2*u].ma,T[2*u+1].ma);
T[u].ma=max(T[u].ma,T[2*u].rmax+T[2*u+1].lmax);
if(T[2*u].lmax==T[2*u].r-T[2*u].l+1)
{
T[u].lmax=T[2*u].lmax+T[2*u+1].lmax;
}
else
T[u].lmax=T[2*u].lmax;
if(T[2*u+1].rmax==T[2*u+1].r-T[2*u+1].l+1)
{
T[u].rmax=T[2*u].rmax+T[2*u+1].rmax;
}
else
T[u].rmax=T[2*u+1].rmax;
if(T[u].ma==T[u].r-T[u].l+1)
T[u].flag1=1;
return 0;
}
int n,k;
int a,b,c;
int main()
{
scanf("%d%d",&n,&k);
build(1,n,1);
int i,j;
for(i=1;i<=k;i++)
{
scanf("%d",&c);
if(c==1)
{
scanf("%d%d",&a,&b);
checkin(a,a+b-1,1);
}
else if(c==2)
{
scanf("%d%d",&a,&b);
checkout(a,a+b-1,1);
}
else
printf("%d\n",T[1].ma);
}
system("pause");
return 0;
}
http://acm.pku.edu.cn/JudgeOnline/problem?id=2828
Buy Tickets
POJ 2828
//按输入的倒序进行操作,可知按倒序排列,插入的位置是最终的位置。
如果插入的位置前有pos-1个空位,则可以插入。后则插在后面
#include<iostream>
using namespace std;
struct node
{
int l,r,c;
}nod[600010];
int a[200001],b[200001],ans[200001];
int build(int s,int e,int u)
{
nod[u].l=s;
nod[u].r=e;
nod[u].c=e-s+1;
if(s<e)
{
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid+1,e,2*u+1);
}
return 0;
}
int solve(int pos,int val,int u)
{
nod[u].c--;
if(nod[u].l==nod[u].r)
{
ans[nod[u].l]=val;
return 0;
}
if(nod[2*u].c>=pos)
solve(pos,val,2*u);
else
solve(pos-nod[2*u].c,val,2*u+1);
return 0;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i;
build(1,n,1);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
a[i]++;
}
for(i=n;i>=1;i--)
solve(a[i],b[i],1);
for(i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[i]);
}
return 0;
}
//按输入的倒序进行操作,可知按倒序排列,插入的位置是最终的位置。
如果插入的位置前有pos-1个空位,则可以插入。后则插在后面
#include<iostream>
using namespace std;
struct node
{
int l,r,c;
}nod[600010];
int a[200001],b[200001],ans[200001];
int build(int s,int e,int u)
{
nod[u].l=s;
nod[u].r=e;
nod[u].c=e-s+1;
if(s<e)
{
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid+1,e,2*u+1);
}
return 0;
}
int solve(int pos,int val,int u)
{
nod[u].c--;
if(nod[u].l==nod[u].r)
{
ans[nod[u].l]=val;
return 0;
}
if(nod[2*u].c>=pos)
solve(pos,val,2*u);
else
solve(pos-nod[2*u].c,val,2*u+1);
return 0;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i;
build(1,n,1);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
a[i]++;
}
for(i=n;i>=1;i--)
solve(a[i],b[i],1);
for(i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[i]);
}
return 0;
}
http://acm.pku.edu.cn/JudgeOnline/problem?id=3277
City Horizon
POJ 3277
//离散化+线段树
//按高度排序后可以直接覆盖掉之前高度小的
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct Node
{
long long l,r,h,mh;
}t[310001];
int map[40100][3];
int tmp[80202];
int n;
long long sum=0;
int find(int t)
{
int l=1,r=tmp[0];
int mid;
while(l<=r)
{
mid=(l+r)>>1;
if(tmp[mid]==t)
return mid;
if(tmp[mid]>t)
r=mid-1;
else
l=mid+1;
}
return mid;
}
int build(int s,int e,int u)
{
t[u].l=s;
t[u].r=e;
t[u].h=0;
t[u].mh=0;
if(s+1<e)
{
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid,e,2*u+1);
}
return 0;
}
int insert(int s,int e,long long h,int u)
{
if(h<t[u].h)
return 0;
if(s<=t[u].l&&e>=t[u].r)
{
if(t[u].h>=0)
{
t[u].h=h;
t[u].mh=h;
return 0;
}
else
{
if(h>=t[u].mh)
{
t[u].h=h;
t[u].mh=h;
return 0;
}
}
}
if(t[u].h>=0)
{
t[2*u].h=t[u].h;
t[2*u].mh=t[u].mh;
t[2*u+1].h=t[u].h;
t[2*u+1].mh=t[u].mh;
t[u].h=-1;
}
if(s<t[2*u].r)
insert(s,e,h,2*u);
if(e>t[2*u+1].l)
insert(s,e,h,2*u+1);
t[u].mh=max(t[2*u].mh,t[2*u+1].mh);
return 0;
}
int check(int s,int e,int u)
{
if(s<=t[u].l&&e>=t[u].r)
{
if(t[u].h>=0)
{
sum+=(tmp[t[u].r]-tmp[t[u].l])*t[u].h;
return 0;
}
}
if(s<t[2*u].r)
check(s,e,2*u);
if(e>t[2*u+1].l)
check(s,e,2*u+1);
return 0;
}
int cmp(const void* lhs, const void* rhs)
{
return ((int*)lhs)[2] - ((int*)rhs)[2];
}
int main()
{
scanf("%d",&n);
int i,j;
tmp[0]=0;
for(i=1;i<=n;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&map[i][j]);
if(j<2)
tmp[++tmp[0]]=map[i][j];
}
}
sort(tmp+1,tmp+2*n+1);
tmp[0]=0;
for(i=1;i<=2*n;i++)
{
if(tmp[i]!=tmp[i-1])
tmp[++tmp[0]]=tmp[i];
}
build(1,tmp[0],1);
qsort(map+1, n, 3*sizeof(int), cmp);
for(i=1;i<=n;i++)
insert(find(map[i][0]),find(map[i][1]),map[i][2],1);
check(1,tmp[0],1);
printf("%lld\n",sum);
/*printf("%d\n",tmp[0]);
for(i=1;i<=tmp[0];i++)
{
printf("%d %d\n",tmp[i],find(tmp[i]));
}*/
system("pause");
return 0;
}
//离散化+线段树
//按高度排序后可以直接覆盖掉之前高度小的
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct Node
{
long long l,r,h,mh;
}t[310001];
int map[40100][3];
int tmp[80202];
int n;
long long sum=0;
int find(int t)
{
int l=1,r=tmp[0];
int mid;
while(l<=r)
{
mid=(l+r)>>1;
if(tmp[mid]==t)
return mid;
if(tmp[mid]>t)
r=mid-1;
else
l=mid+1;
}
return mid;
}
int build(int s,int e,int u)
{
t[u].l=s;
t[u].r=e;
t[u].h=0;
t[u].mh=0;
if(s+1<e)
{
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid,e,2*u+1);
}
return 0;
}
int insert(int s,int e,long long h,int u)
{
if(h<t[u].h)
return 0;
if(s<=t[u].l&&e>=t[u].r)
{
if(t[u].h>=0)
{
t[u].h=h;
t[u].mh=h;
return 0;
}
else
{
if(h>=t[u].mh)
{
t[u].h=h;
t[u].mh=h;
return 0;
}
}
}
if(t[u].h>=0)
{
t[2*u].h=t[u].h;
t[2*u].mh=t[u].mh;
t[2*u+1].h=t[u].h;
t[2*u+1].mh=t[u].mh;
t[u].h=-1;
}
if(s<t[2*u].r)
insert(s,e,h,2*u);
if(e>t[2*u+1].l)
insert(s,e,h,2*u+1);
t[u].mh=max(t[2*u].mh,t[2*u+1].mh);
return 0;
}
int check(int s,int e,int u)
{
if(s<=t[u].l&&e>=t[u].r)
{
if(t[u].h>=0)
{
sum+=(tmp[t[u].r]-tmp[t[u].l])*t[u].h;
return 0;
}
}
if(s<t[2*u].r)
check(s,e,2*u);
if(e>t[2*u+1].l)
check(s,e,2*u+1);
return 0;
}
int cmp(const void* lhs, const void* rhs)
{
return ((int*)lhs)[2] - ((int*)rhs)[2];
}
int main()
{
scanf("%d",&n);
int i,j;
tmp[0]=0;
for(i=1;i<=n;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&map[i][j]);
if(j<2)
tmp[++tmp[0]]=map[i][j];
}
}
sort(tmp+1,tmp+2*n+1);
tmp[0]=0;
for(i=1;i<=2*n;i++)
{
if(tmp[i]!=tmp[i-1])
tmp[++tmp[0]]=tmp[i];
}
build(1,tmp[0],1);
qsort(map+1, n, 3*sizeof(int), cmp);
for(i=1;i<=n;i++)
insert(find(map[i][0]),find(map[i][1]),map[i][2],1);
check(1,tmp[0],1);
printf("%lld\n",sum);
/*printf("%d\n",tmp[0]);
for(i=1;i<=tmp[0];i++)
{
printf("%d %d\n",tmp[i],find(tmp[i]));
}*/
system("pause");
return 0;
}
http://acm.pku.edu.cn/JudgeOnline/problem?id=3368
Frequent Values
POJ 3268
//对于[a,b][b+1,c],若f[b]==b[b+1],则ma=max([a,b],[b+1,c],[a,b][b+1,c]);
#include<iostream>
#include<cmath>
using namespace std;
struct node
{
int l,r,lmax,rmax,ma;
}t[400000];
int a[100001];
int sum;
int build(int s,int e,int u)
{
t[u].l=s;
t[u].r=e;
if(s==e)
{
t[u].lmax=t[u].rmax=t[u].ma=1;
return 0;
}
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid+1,e,2*u+1);
t[u].ma=max(t[2*u].ma,t[2*u+1].ma);
t[u].lmax=t[2*u].lmax;
t[u].rmax=t[2*u+1].rmax;
if(a[t[2*u].r]==a[t[2*u+1].l])
{
int sum=t[2*u].rmax+t[2*u+1].lmax;
t[u].ma=max(t[u].ma,sum);
if(a[t[u].l]==a[t[2*u].r])
t[u].lmax=sum;
if(a[t[u].r]==a[t[2*u+1].l])
t[u].rmax=sum;
}
return 0;
}
int check(int s,int e,int u)
{
if(s==t[u].l&&e==t[u].r)
{
return t[u].ma;
}
if(e<=t[2*u].r)
return check(s,e,2*u);
if(s>=t[2*u+1].l)
{
return check(s,e,2*u+1);
}
int q1,q2;
q1=check(s,t[2*u].r,2*u);
q2=check(t[2*u+1].l,e,2*u+1);
int tmp=max(q1,q2);
if(a[t[2*u].r]==a[t[2*u+1].l])
{
tmp=max(tmp,min(t[2*u].rmax,t[2*u].r-s+1)+min(t[2*u+1].lmax,e-t[2*u+1].l+1));
}
return tmp;
}
int n,q;
int main()
{
while(scanf("%d",&n),n)
{
scanf("%d",&q);
int i;
int x,y;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,n,1);
for(i=1;i<=q;i++)
{
sum=0;
scanf("%d%d",&x,&y);
printf("%d\n",check(x,y,1));
}
}
system("pause");
return 0;
}
//对于[a,b][b+1,c],若f[b]==b[b+1],则ma=max([a,b],[b+1,c],[a,b][b+1,c]);
#include<iostream>
#include<cmath>
using namespace std;
struct node
{
int l,r,lmax,rmax,ma;
}t[400000];
int a[100001];
int sum;
int build(int s,int e,int u)
{
t[u].l=s;
t[u].r=e;
if(s==e)
{
t[u].lmax=t[u].rmax=t[u].ma=1;
return 0;
}
int mid=(s+e)>>1;
build(s,mid,2*u);
build(mid+1,e,2*u+1);
t[u].ma=max(t[2*u].ma,t[2*u+1].ma);
t[u].lmax=t[2*u].lmax;
t[u].rmax=t[2*u+1].rmax;
if(a[t[2*u].r]==a[t[2*u+1].l])
{
int sum=t[2*u].rmax+t[2*u+1].lmax;
t[u].ma=max(t[u].ma,sum);
if(a[t[u].l]==a[t[2*u].r])
t[u].lmax=sum;
if(a[t[u].r]==a[t[2*u+1].l])
t[u].rmax=sum;
}
return 0;
}
int check(int s,int e,int u)
{
if(s==t[u].l&&e==t[u].r)
{
return t[u].ma;
}
if(e<=t[2*u].r)
return check(s,e,2*u);
if(s>=t[2*u+1].l)
{
return check(s,e,2*u+1);
}
int q1,q2;
q1=check(s,t[2*u].r,2*u);
q2=check(t[2*u+1].l,e,2*u+1);
int tmp=max(q1,q2);
if(a[t[2*u].r]==a[t[2*u+1].l])
{
tmp=max(tmp,min(t[2*u].rmax,t[2*u].r-s+1)+min(t[2*u+1].lmax,e-t[2*u+1].l+1));
}
return tmp;
}
int n,q;
int main()
{
while(scanf("%d",&n),n)
{
scanf("%d",&q);
int i;
int x,y;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,n,1);
for(i=1;i<=q;i++)
{
sum=0;
scanf("%d%d",&x,&y);
printf("%d\n",check(x,y,1));
}
}
system("pause");
return 0;
}