版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/88054347
分析:
KD-tree+查询历史最大值
懒标记很多,有点麻烦。
代码里有注释
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 350010
using namespace std;
struct node{
int x,y,Maxx,Maxy,Minx,Miny,id;
node* l,*r,*fa;
int Maxv;//Maxv ths max number of cover the whole section
int ans;//The ans in this segment
int now;//The number of cover the whole section now
int pre;//The number of cover the whole section,and pushdown it to update subtree
int sum;//The number of cover this segment now
bool clr;
void pushdown(){
if(clr==0) pre=now;
Maxv=max(Maxv,now);
ans=max(ans,max(sum,Maxv));
if(l!=NULL){
l->Maxv=max(l->Maxv,Maxv);
if(clr){
if(l->clr==0)
l->clr=1,l->pre=l->now+pre;
l->Maxv=max(l->Maxv,l->now+pre);
l->ans=max(l->ans,l->sum+pre);
l->sum=l->now=now;
}
else
l->now+=pre,l->sum+=pre;
}
if(r!=NULL){
r->Maxv=max(r->Maxv,Maxv);
if(clr){
if(r->clr==0)
r->clr=1,r->pre=r->now+pre;
r->Maxv=max(r->Maxv,r->now+pre);
r->ans=max(r->ans,r->sum+pre);
r->sum=r->now=now;
}
else
r->now+=pre,r->sum+=pre;
}
clr=0;
now=pre=0;
}
}t[MAXN],*rt;
bool cmpx(const node &a,const node &b){
return a.x<b.x;
}
bool cmpy(const node &a,const node &b){
return a.y<b.y;
}
node* build(int l,int r){
int mid=(l+r)>>1;
if(rand()%2==1)
nth_element(t+l,t+mid,t+r+1,cmpx);
else
nth_element(t+l,t+mid,t+r+1,cmpy);
swap(t[l],t[mid]);
t[l].Maxx=t[l].Minx=t[l].x;
t[l].Maxy=t[l].Miny=t[l].y;
if(l!=mid){
node *y=build(l+1,mid);
y->fa=&t[l];
t[l].l=y;
t[l].Maxx=max(t[l].Maxx,y->Maxx);
t[l].Maxy=max(t[l].Maxy,y->Maxy);
t[l].Minx=min(t[l].Minx,y->Minx);
t[l].Miny=min(t[l].Miny,y->Miny);
}
if(r!=mid){
node *y=build(mid+1,r);
y->fa=&t[l];
t[l].r=y;
t[l].Maxx=max(t[l].Maxx,y->Maxx);
t[l].Maxy=max(t[l].Maxy,y->Maxy);
t[l].Minx=min(t[l].Minx,y->Minx);
t[l].Miny=min(t[l].Miny,y->Miny);
}
return t+l;
}
int L,R;
int pos[MAXN];
void calc(node *x){
if(x->Minx>R||x->Maxy<L){
if(x->clr==0) x->pre=x->now;
x->Maxv=max(x->Maxv,x->now);
x->ans=max(x->ans,x->sum);
x->sum=x->now=0;
x->clr=1;
return ;
}
if(x->Maxx<=R&&x->Miny>=L){
x->sum++,x->now++;
return ;
}
if(x->clr||x->pre||x->now) x->pushdown();
if(x->x<=R&&x->y>=L){
x->sum++;
x->ans=max(x->ans,x->sum);
}
else{
x->ans=max(x->ans,x->sum);
x->sum=0;
}
if(x->l) calc(x->l);
if(x->r) calc(x->r);
}
char S[20];
int main(){
freopen("bomb.in","r",stdin);
freopen("bomb.out","w",stdout);
srand(0);
int n,m,q,u;
SF("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++){
SF("%d%d",&t[i].x,&t[i].y);
t[i].id=i;
}
rt=build(1,n);
for(int i=1;i<=n;i++)
pos[t[i].id]=i;
for(int i=1;i<=m;i++){
SF("%d%d",&L,&R);
calc(rt);
}
for(int i=1;i<=q;i++){
SF("%s",S);
if(S[0]=='A'){
SF("%d%d",&L,&R);
calc(rt);
}
if(S[0]=='C'){
SF("%d",&u);
u=pos[u];
int ans=t[u].ans;
int sum=t[u].sum;
for(node *x=t[u].fa;x;x=x->fa){
ans=max(ans,x->Maxv);
if(x->clr){
ans=max(ans,sum+x->pre);
sum=0;
}
sum+=x->now;
}
ans=max(ans,sum);
PF("%d\n",ans);
}
if(S[0]=='Q'){
int ans=0;
for(int i=1;i<=n;i++){
if(t[i].pre||t[i].clr||t[i].now)
t[i].pushdown();
ans^=t[i].ans;
}
PF("%d\n",ans);
}
}
}