版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82877869
题解:
KD树支持矩阵加1,矩阵赋0,查询历史最大值。
时间复杂度 。
代码标记用了二元组,没把常数压下去。。
#include <bits/stdc++.h>
using namespace std;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
inline void W(int x) {
static int buf[50];
if(!x) {putchar('0'); return;}
if(x<0) {putchar('-'); x=-x;}
while(x) {buf[++buf[0]]=x%10; x/=10;}
while(buf[0]) {putchar(buf[buf[0]--]+'0');}
}
const int N=5e4+50, INF=0x3f3f3f3f;
int n,m,q,tot;
inline int Max(int x,int y) {return (x>y) ? x : y;}
inline int Min(int x,int y) {return (x<y) ? x : y;}
struct tag {
int x,y;
tag(int x=0,int y=-INF) : x(x), y(y) {}
friend inline tag operator +(const tag &a,const tag &b) {return tag(Max(a.x+b.x,-INF),Max(a.y+b.x,b.y));}
friend inline tag max(const tag &a,const tag &b) {return tag(Max(a.x,b.x),Max(a.y,b.y));}
friend inline bool operator ==(const tag &a,const tag &b) {return a.x==b.x && a.y==b.y;}
};
const tag A(1,0), B(-INF,0);
struct P {
int x,y;
P(int x=0,int y=0) : x(x),y(y) {}
friend inline P max(const P &a,const P &b) {return P(Max(a.x,b.x),Max(a.y,b.y));}
friend inline P min(const P &a,const P &b) {return P(Min(a.x,b.x),Min(a.y,b.y));}
friend inline bool operator ==(const P &a,const P &b) {return a.x==b.x && a.y==b.y;}
} po[N], tp[N];
inline bool cmpx(const P &a,const P &b) {return a.x<b.x || (a.x==b.x&&a.y<b.y);}
inline bool cmpy(const P &a,const P &b) {return a.y<b.y || (a.y==b.y&&a.x<b.x);}
struct node {
P p,mx,mn;
int lc,rc;
tag ptag,ntag;
int pmax,nmax;
node():lc(0),rc(0) {}
} tr[N];
#define sqr(x) ((x)*(x))
inline void build(int &k,int l,int r) {
k=++tot; int mid=(l+r)>>1;
double avex=0, avey=0, sumx=0, sumy=0;
for(int i=l;i<=r;++i) avex+=tp[i].x, avey+=tp[i].y;
avex/=(r-l+1); avey/=(r-l+1);
for(int i=l;i<=r;++i) sumx+=sqr(tp[i].x-avex), sumy+=sqr(tp[i].y-avey);
if(sumx>sumy) nth_element(tp+l,tp+mid,tp+r+1,cmpx);
else nth_element(tp+l,tp+mid,tp+r+1,cmpy);
tr[k].p=tr[k].mx=tr[k].mn=tp[mid];
if(l<mid) {
build(tr[k].lc,l,mid-1);
tr[k].mx=max(tr[k].mx,tr[tr[k].lc].mx);
tr[k].mn=min(tr[k].mn,tr[tr[k].lc].mn);
}
if(r>mid) {
build(tr[k].rc,mid+1,r);
tr[k].mx=max(tr[k].mx,tr[tr[k].rc].mx);
tr[k].mn=min(tr[k].mn,tr[tr[k].rc].mn);
}
}
inline void add_tag(int k,tag px,tag nx) {
tr[k].ptag=max(tr[k].ptag,tr[k].ntag+px);
tr[k].ntag=tr[k].ntag+nx;
tr[k].pmax=Max(tr[k].pmax,Max(tr[k].nmax+px.x,px.y));
tr[k].nmax=Max(tr[k].nmax+nx.x,nx.y);
}
inline void add_val(int k,tag t) {
tr[k].nmax=Max(tr[k].nmax+t.x,t.y);
tr[k].pmax=Max(tr[k].pmax,tr[k].nmax);
}
inline void pushdown(int k) {
if(tr[k].ntag==tr[k].ptag && tr[k].ntag==tag()) return;
if(tr[k].lc) add_tag(tr[k].lc,tr[k].ptag,tr[k].ntag);
if(tr[k].rc) add_tag(tr[k].rc,tr[k].ptag,tr[k].ntag);
tr[k].ptag=tr[k].ntag=tag();
}
inline int in(P mn,P mx,int l,int r,int L,int R) {
if(l<=mn.x && mx.x<=r && L<=mn.y && mx.y<=R) return 1;
if(mx.x<l || mn.x>r || mx.y<L || mn.y>R) return -1;
return 0;
}
inline void modify(int k,int l,int r,int L,int R) {
pushdown(k); int v=in(tr[k].mn,tr[k].mx,l,r,L,R);
if(!~v) {add_tag(k,B,B); return;}
if(v) {add_tag(k,A,A); return;}
if(in(tr[k].p,tr[k].p,l,r,L,R)==1) add_val(k,A);
else add_val(k,B);
if(tr[k].lc) modify(tr[k].lc,l,r,L,R);
if(tr[k].rc) modify(tr[k].rc,l,r,L,R);
}
inline int ask(int k,int l,int r) {
pushdown(k); int v=in(tr[k].mn,tr[k].mx,l,l,r,r);
if(!~v) return 0;
if(tr[k].p.x==l && tr[k].p.y==r) return tr[k].pmax;
v=0;
if(tr[k].lc) v+=ask(tr[k].lc,l,r);
if(tr[k].rc) v+=ask(tr[k].rc,l,r);
return v;
}
inline int dfs(int x) {
int val=tr[x].pmax;
pushdown(x);
if(tr[x].lc) val^=dfs(tr[x].lc);
if(tr[x].rc) val^=dfs(tr[x].rc);
return val;
}
int main() {
n=rd(), m=rd(), q=rd();
for(int i=1;i<=n;i++) po[i].x=rd(), po[i].y=rd();
memcpy(tp+1,po+1,sizeof(P)*n);
sort(tp+1,tp+n+1,cmpx);
int tot=unique(tp+1,tp+n+1)-tp-1;
int rt; build(rt,1,tot);
for(int i=1;i<=m;i++) {
int l=rd(), r=rd();
modify(1,-INF,r,l,INF);
}
for(int i=1;i<=q;i++) {
char op=nc(); while(isspace(op)) op=nc();
if(op=='A') {
int l=rd(), r=rd();
modify(1,-INF,r,l,INF);
} else if(op=='C') {
int id=rd();
W(ask(1,po[id].x,po[id].y)), putchar('\n');
} else {
W(dfs(1)), putchar('\n');
}
}
}