二维恶心强制在线卡空间数点(主席树+KD树)

在这里插入图片描述为啥要主席树加KD树?
因为这个恶心出题人强制在线卡空间卡时间。
主席树处理询问 3 3
KD树处理 = 1 , 2 =1,2
勉强卡过时限。

#include<bits/stdc++.h>
#define maxn 800005
#define Ct const
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
using namespace std;

char cb[1<<16],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<16,stdin),cs==ct)?0:*cs++)
void read(int &res){char ch;bool f =0;
	for(;!isdigit(ch=getc());) if(ch=='-') f=1;
	for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
	(f) && (res=-res);
}

int tot,rtj,rtp,D,c[maxn];
struct node{
	int a[2],sz,sm,v,mn[2],mx[2],ch[2],d;
	void upd(node *P){
		sm=v,sz=1;
		rep(i,0,1) mn[i]=mx[i]=a[i];
		rep(j,0,1) if(ch[j]){
			rep(i,0,1)
				mn[i]=min(mn[i],P[ch[j]].mn[i]),
				mx[i]=max(mx[i],P[ch[j]].mx[i]);
			sm+=P[ch[j]].sm,sz+=P[ch[j]].sz;
		}
	}
}P[maxn];
#define upd() upd(P)
bool cmp(Ct int &u,Ct int &v){ return P[u].a[D]<P[v].a[D]; }
void Build(int &u,int l,int r,int nD){
	if(l>r) return;
	int m=l+r>>1;D=nD,nth_element(c+l,c+m,c+r+1,cmp);u=c[m];
	Build(P[u].ch[0],l,m-1,nD^1),Build(P[u].ch[1],m+1,r,nD^1);
	P[u].d=nD,P[u].upd();
}
int *mtp;
bool chk(int u,int v){
	return P[v].sz  > P[u].sz * 0.75 + 3;
}
void ins(int &u,int p,int nD){
	if(!u) return (void)(P[u=p].upd(),P[u].d=nD);
	D=nD;
	if(cmp(u,p)) ins(P[u].ch[1],p,nD^1);
	else ins(P[u].ch[0],p,nD^1);
	P[u].upd();
	if(chk(u,P[u].ch[0]) || chk(u,P[u].ch[1]))
		mtp = &u;
}
void dfs(int u){
	if(!u) return;
	c[++c[0]]=u;
	dfs(P[u].ch[0]),dfs(P[u].ch[1]);
	P[u].ch[0]=P[u].ch[1]=0;
}
int qry(int u,int mn[],int mx[],int nD){
	if(!u || mn[0]>P[u].mx[0] || mn[1]>P[u].mx[1] || 
		mx[0]<P[u].mn[0] || mx[1]<P[u].mn[1]) return 0;
	if(mn[0] <= P[u].mn[0] && mx[0] >= P[u].mx[0] && 
		mn[1] <= P[u].mn[1] && mx[1] >= P[u].mx[1]) return P[u].sm;
	int r = qry(P[u].ch[0],mn,mx,nD^1) + qry(P[u].ch[1],mn,mx,nD^1);
	if(mn[0] <= P[u].a[0] && mx[0] >= P[u].a[0] && 
		mn[1] <= P[u].a[1] && mx[1] >= P[u].a[1])
		 	r+=P[u].v;
	return r;
}

int n,m,q,X1[maxn],X2[maxn],Y1[maxn],Y2[maxn],sb[maxn],null;
int lc[maxn*30],rc[maxn*30],sm[maxn*30],rt[maxn],cnt_p;
vector<int>G[maxn];
void ins(int &u,int l,int r,int p,int v){
	sm[++cnt_p]=sm[u]+v,lc[cnt_p]=lc[u],rc[cnt_p]=rc[u];
	u=cnt_p;
	if(l==r) return;
	int m=l+r>>1;p<=m?ins(lc[u],l,m,p,v):ins(rc[u],m+1,r,p,v);
}
int qry(int u,int l,int r,int ql,int qr){
	if(!u || l>qr || ql>r) return 0;
	if(ql<=l&&r<=qr) return sm[u];
	int m=l+r>>1;return qry(lc[u],l,m,ql,qr)+qry(rc[u],m+1,r,ql,qr);
}

int main(){ 

	freopen("datastructure.in","r",stdin);
	freopen("datastructure.out","w",stdout);

	read(n),read(m);
	rep(i,1,n){
		read(X1[i]),read(Y1[i]),read(X2[i]),read(Y2[i]);X2[i]++,Y2[i]++;
		P[++tot].a[0]=X1[i],P[tot].a[1]=Y1[i],P[tot].v=1;
		P[++tot].a[0]=X2[i],P[tot].a[1]=Y1[i],P[tot].v=-1;
		P[++tot].a[0]=X1[i],P[tot].a[1]=Y2[i],P[tot].v=-1;
		P[++tot].a[0]=X2[i],P[tot].a[1]=Y2[i],P[tot].v=1;
		sb[++sb[0]]=X1[i],
		sb[++sb[0]]=X2[i],
		sb[++sb[0]]=Y1[i],
		sb[++sb[0]]=Y2[i];
	}
	sort(sb+1,sb+1+sb[0]),sb[0]=unique(sb+1,sb+1+sb[0])-sb-1;
	rep(i,1,tot){
		P[i].a[0]=lower_bound(sb+1,sb+1+sb[0],P[i].a[0])-sb;
		P[i].a[1]=lower_bound(sb+1,sb+1+sb[0],P[i].a[1])-sb;
		G[P[i].a[0]].push_back(i);
	}
	rep(i,1,sb[0]){
		rt[i]=rt[i-1];
		rep(j,0,G[i].size()-1)
			ins(rt[i],1,sb[0],P[G[i][j]].a[1],P[G[i][j]].v);
	}
	rep(i,1,m){
		read(P[++tot].a[0]),read(P[tot].a[1]);
		P[tot].v=1;
		c[++c[0]]=tot;
	}
	Build(rtp,1,c[0],0);
	int las=0,a,mn[2],mx[2];
	read(q),read(a);
	for(;q--;){
		int op,x,y;
		read(op);
		if(op == 1){
			read(P[++tot].a[0]),read(P[tot].a[1]),P[tot].v=1;
			P[tot].a[0]+=las*a;
			P[tot].a[1]+=las*a;
			mtp=&null;ins(rtp,tot,0);
			if(*mtp){
				c[0]=0;dfs(*mtp);
				Build(*mtp,1,c[0],P[*mtp].d);
			}
		}
		else if(op == 2){
			read(x);x+=las*a;
			mn[0]=X1[x],mn[1]=Y1[x];
			mx[0]=X2[x]-1,mx[1]=Y2[x]-1;
			printf("%d\n",las=qry(rtp,mn,mx,0));
		}
		else{
			read(P[0].a[0]),read(P[0].a[1]);
			P[0].a[0]+=las*a;
			P[0].a[1]+=las*a;
			P[0].a[0]=upper_bound(sb+1,sb+1+sb[0],P[0].a[0])-sb-1;
			P[0].a[1]=upper_bound(sb+1,sb+1+sb[0],P[0].a[1])-sb-1;
			printf("%d\n",las=qry(rt[P[0].a[0]],1,sb[0],1,P[0].a[1]));
		}
	}
}
发布了627 篇原创文章 · 获赞 91 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/103810535