记录编号 410783 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]Attack 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 21.142 s
提交时间 2017-06-02 16:16:53 内存使用 355.25 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e5+10,M=3e7+10;
struct Node{int l,r,v;}node[M];
int n,m,id,x[N],y[N],z[N],ax[N],ay[N],az[N];
int rankl(int *a,int x){//第一个>=x的数
	int l=0,r=n+1;
	while (l<r){
		int mid=(l+r)>>1;
		if (a[mid]>=x) r=mid;else l=mid+1;
	}
	return l;
}
int rankr(int *a,int x){//第一个<=x的数
	int l=0,r=n+1;
	while (l<r){
		int mid=(l+r)>>1;
		if (a[mid+1]<=x) l=mid+1;else r=mid;
	}
	return l;
}
void add(int x,int p,int d){//一维单点修改
	int l=1,r=n;
	while (1){
		node[x].v+=d;
		if (l==r) return;
		int mid=(l+r)>>1;
		if (p>mid){
			if (!node[x].r) node[x].r=++id;
			x=node[x].r;
			l=mid+1;
		}
		else{
			if (!node[x].l) node[x].l=++id;
			x=node[x].l;
			r=mid;
		}
	}
}
int sum(int x,int l,int r,int L,int R){
	if (l>=L&&r<=R) return node[x].v;
	int mid=(l+r)>>1,ans=0;
	if (L<=mid) ans+=sum(node[x].l,l,mid,L,R);
	if (R>mid) ans+=sum(node[x].r,mid+1,r,L,R);
	return ans;
}
void ins(int X,int Y,int d){
	int l=1,r=n,x=1;
	while (1){
		if (!node[x].v) node[x].v=++id;
		add(node[x].v,Y,d);
		if (l==r) return;
		int mid=(l+r)>>1;
		if (X>mid){
			if (!node[x].r) node[x].r=++id;
			x=node[x].r;
			l=mid+1;
		}
		else{
			if (!node[x].l) node[x].l=++id;
			x=node[x].l;
			r=mid;
		}
	}
}
int sum(int x,int l,int r,int x1,int y1,int x2,int y2){
	if (l>=x1&&r<=x2) return sum(node[x].v,1,n,y1,y2);
	int mid=(l+r)>>1,ans=0;
	if (x1<=mid) ans+=sum(node[x].l,l,mid,x1,y1,x2,y2);
	if (x2>mid) ans+=sum(node[x].r,mid+1,r,x1,y1,x2,y2);
	return ans;
}
struct opt{int id,tp,x1,y1,x2,y2,k,d;}Q[N];
int ans[N],cnt;bool ask[N];
//d=+-1表示修改,否则表示查询
bool cmp(const opt &x,const opt &y){return x.tp==y.tp?x.id<y.id:x.tp<y.tp;}
void solve(int l,int r,int L,int R){//答案区间为[l,r],操作区间为[L,R]
	if (L>R) return;
	if (l==r){
		for (int i=L;i<=R;i++)
			if (!Q[i].d) ans[Q[i].id]=l;
		return;
	}
	int cnt=0;
	//初始化
	for (;id;id--) node[id].l=node[id].r=node[id].v=0;id=1;
	int mid=(l+r)>>1;
	for (int i=L;i<=R;i++)
	if (Q[i].d){
		if (Q[i].k<=mid) ins(Q[i].x1,Q[i].y1,Q[i].d),Q[i].tp=0,cnt++;
			else Q[i].tp=1;
	}
	else{
		int s;
		if (Q[i].x1>Q[i].x2||Q[i].y1>Q[i].y2) s=0;
			else s=sum(1,1,n,Q[i].x1,Q[i].y1,Q[i].x2,Q[i].y2);
		if (s>=Q[i].k) Q[i].tp=0,cnt++;
			else Q[i].k-=s,Q[i].tp=1;
	}
	sort(Q+L,Q+R+1,cmp);
	solve(l,mid,L,L+cnt-1);
	solve(mid+1,r,L+cnt,R);
}
int main()
{
	freopen("nt2012_attack.in","r",stdin);
	freopen("nt2012_attack.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++){
		scanf("%d%d%d",&x[i],&y[i],&z[i]);
		ax[i]=x[i];ay[i]=y[i];az[i]=z[i];
	}
	sort(ax+1,ax+n+1);ax[n+1]=1e9;
	sort(ay+1,ay+n+1);ay[n+1]=1e9;
	sort(az+1,az+n+1);az[n+1]=1e9;
	for (int i=1;i<=n;i++){
		x[i]=rankl(ax,x[i]);
		y[i]=rankl(ay,y[i]);
		z[i]=rankl(az,z[i]);
		cnt++;Q[cnt]=(opt){cnt,0,x[i],y[i],0,0,z[i],1};
	}
	char tp[10];int x1,y1,x2,y2,k;
	while (m--){
		scanf("%s%d%d",tp,&x1,&y1);
		if (tp[0]=='Q'){
			scanf("%d%d%d",&x2,&y2,&k);
			if (x1>x2) swap(x1,x2);
			if (y1>y2) swap(y1,y2);
			x1=rankl(ax,x1);
			y1=rankl(ay,y1);
			x2=rankr(ax,x2);
			y2=rankr(ay,y2);
			//printf("[(%d,%d),(%d,%d)]\n",x1,y1,x2,y2);
			ask[++cnt]=1;
			Q[cnt]=(opt){cnt,0,x1,y1,x2,y2,k,0};
		}
		else{
			x1++;y1++;
			cnt++;Q[cnt]=(opt){cnt,0,x[x1],y[x1],0,0,z[x1],-1};
			cnt++;Q[cnt]=(opt){cnt,0,x[y1],y[y1],0,0,z[y1],-1};
			swap(z[x1],z[y1]);
			cnt++;Q[cnt]=(opt){cnt,0,x[x1],y[x1],0,0,z[x1],1};
			cnt++;Q[cnt]=(opt){cnt,0,x[y1],y[y1],0,0,z[y1],1};
		}
	}
	solve(1,n+1,1,cnt);
	for (int i=1;i<=cnt;i++) if (ask[i])
		ans[i]<=n?printf("%d\n",az[ans[i]]):puts("It doesn't exist.");
	return 0;
}