记录编号 |
410783 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[国家集训队2012]Attack |
最终得分 |
100 |
用户昵称 |
FoolMike |
是否通过 |
通过 |
代码语言 |
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;
}