BZOJ5223: [Lydsy2017省队十连测]有理有据题(KD树)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82877869

传送门

题解:
KD树支持矩阵加1,矩阵赋0,查询历史最大值。

时间复杂度 O ( ( m + A ) n + C log n + q n ) O((m+A)\sqrt{n} + C \log n + qn)

代码标记用了二元组,没把常数压下去。。

#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');
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_35649707/article/details/82877869
今日推荐