记录编号 410783 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]Attack 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 21.142 s
提交时间 2017-06-02 16:16:53 内存使用 355.25 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N=2e5+10,M=3e7+10;
  5. struct Node{int l,r,v;}node[M];
  6. int n,m,id,x[N],y[N],z[N],ax[N],ay[N],az[N];
  7. int rankl(int *a,int x){//第一个>=x的数
  8. int l=0,r=n+1;
  9. while (l<r){
  10. int mid=(l+r)>>1;
  11. if (a[mid]>=x) r=mid;else l=mid+1;
  12. }
  13. return l;
  14. }
  15. int rankr(int *a,int x){//第一个<=x的数
  16. int l=0,r=n+1;
  17. while (l<r){
  18. int mid=(l+r)>>1;
  19. if (a[mid+1]<=x) l=mid+1;else r=mid;
  20. }
  21. return l;
  22. }
  23. void add(int x,int p,int d){//一维单点修改
  24. int l=1,r=n;
  25. while (1){
  26. node[x].v+=d;
  27. if (l==r) return;
  28. int mid=(l+r)>>1;
  29. if (p>mid){
  30. if (!node[x].r) node[x].r=++id;
  31. x=node[x].r;
  32. l=mid+1;
  33. }
  34. else{
  35. if (!node[x].l) node[x].l=++id;
  36. x=node[x].l;
  37. r=mid;
  38. }
  39. }
  40. }
  41. int sum(int x,int l,int r,int L,int R){
  42. if (l>=L&&r<=R) return node[x].v;
  43. int mid=(l+r)>>1,ans=0;
  44. if (L<=mid) ans+=sum(node[x].l,l,mid,L,R);
  45. if (R>mid) ans+=sum(node[x].r,mid+1,r,L,R);
  46. return ans;
  47. }
  48. void ins(int X,int Y,int d){
  49. int l=1,r=n,x=1;
  50. while (1){
  51. if (!node[x].v) node[x].v=++id;
  52. add(node[x].v,Y,d);
  53. if (l==r) return;
  54. int mid=(l+r)>>1;
  55. if (X>mid){
  56. if (!node[x].r) node[x].r=++id;
  57. x=node[x].r;
  58. l=mid+1;
  59. }
  60. else{
  61. if (!node[x].l) node[x].l=++id;
  62. x=node[x].l;
  63. r=mid;
  64. }
  65. }
  66. }
  67. int sum(int x,int l,int r,int x1,int y1,int x2,int y2){
  68. if (l>=x1&&r<=x2) return sum(node[x].v,1,n,y1,y2);
  69. int mid=(l+r)>>1,ans=0;
  70. if (x1<=mid) ans+=sum(node[x].l,l,mid,x1,y1,x2,y2);
  71. if (x2>mid) ans+=sum(node[x].r,mid+1,r,x1,y1,x2,y2);
  72. return ans;
  73. }
  74. struct opt{int id,tp,x1,y1,x2,y2,k,d;}Q[N];
  75. int ans[N],cnt;bool ask[N];
  76. //d=+-1表示修改,否则表示查询
  77. bool cmp(const opt &x,const opt &y){return x.tp==y.tp?x.id<y.id:x.tp<y.tp;}
  78. void solve(int l,int r,int L,int R){//答案区间为[l,r],操作区间为[L,R]
  79. if (L>R) return;
  80. if (l==r){
  81. for (int i=L;i<=R;i++)
  82. if (!Q[i].d) ans[Q[i].id]=l;
  83. return;
  84. }
  85. int cnt=0;
  86. //初始化
  87. for (;id;id--) node[id].l=node[id].r=node[id].v=0;id=1;
  88. int mid=(l+r)>>1;
  89. for (int i=L;i<=R;i++)
  90. if (Q[i].d){
  91. if (Q[i].k<=mid) ins(Q[i].x1,Q[i].y1,Q[i].d),Q[i].tp=0,cnt++;
  92. else Q[i].tp=1;
  93. }
  94. else{
  95. int s;
  96. if (Q[i].x1>Q[i].x2||Q[i].y1>Q[i].y2) s=0;
  97. else s=sum(1,1,n,Q[i].x1,Q[i].y1,Q[i].x2,Q[i].y2);
  98. if (s>=Q[i].k) Q[i].tp=0,cnt++;
  99. else Q[i].k-=s,Q[i].tp=1;
  100. }
  101. sort(Q+L,Q+R+1,cmp);
  102. solve(l,mid,L,L+cnt-1);
  103. solve(mid+1,r,L+cnt,R);
  104. }
  105. int main()
  106. {
  107. freopen("nt2012_attack.in","r",stdin);
  108. freopen("nt2012_attack.out","w",stdout);
  109. scanf("%d%d",&n,&m);
  110. for (int i=1;i<=n;i++){
  111. scanf("%d%d%d",&x[i],&y[i],&z[i]);
  112. ax[i]=x[i];ay[i]=y[i];az[i]=z[i];
  113. }
  114. sort(ax+1,ax+n+1);ax[n+1]=1e9;
  115. sort(ay+1,ay+n+1);ay[n+1]=1e9;
  116. sort(az+1,az+n+1);az[n+1]=1e9;
  117. for (int i=1;i<=n;i++){
  118. x[i]=rankl(ax,x[i]);
  119. y[i]=rankl(ay,y[i]);
  120. z[i]=rankl(az,z[i]);
  121. cnt++;Q[cnt]=(opt){cnt,0,x[i],y[i],0,0,z[i],1};
  122. }
  123. char tp[10];int x1,y1,x2,y2,k;
  124. while (m--){
  125. scanf("%s%d%d",tp,&x1,&y1);
  126. if (tp[0]=='Q'){
  127. scanf("%d%d%d",&x2,&y2,&k);
  128. if (x1>x2) swap(x1,x2);
  129. if (y1>y2) swap(y1,y2);
  130. x1=rankl(ax,x1);
  131. y1=rankl(ay,y1);
  132. x2=rankr(ax,x2);
  133. y2=rankr(ay,y2);
  134. //printf("[(%d,%d),(%d,%d)]\n",x1,y1,x2,y2);
  135. ask[++cnt]=1;
  136. Q[cnt]=(opt){cnt,0,x1,y1,x2,y2,k,0};
  137. }
  138. else{
  139. x1++;y1++;
  140. cnt++;Q[cnt]=(opt){cnt,0,x[x1],y[x1],0,0,z[x1],-1};
  141. cnt++;Q[cnt]=(opt){cnt,0,x[y1],y[y1],0,0,z[y1],-1};
  142. swap(z[x1],z[y1]);
  143. cnt++;Q[cnt]=(opt){cnt,0,x[x1],y[x1],0,0,z[x1],1};
  144. cnt++;Q[cnt]=(opt){cnt,0,x[y1],y[y1],0,0,z[y1],1};
  145. }
  146. }
  147. solve(1,n+1,1,cnt);
  148. for (int i=1;i<=cnt;i++) if (ask[i])
  149. ans[i]<=n?printf("%d\n",az[ans[i]]):puts("It doesn't exist.");
  150. return 0;
  151. }