CANCEL操作可以看作删点,X坐标可以离散化

将询问按Z坐标差分,转化成两个求Z<=某个数的和的询问

将操作CDQ分治

每次将前一半的修改、后一半的查询按照Z坐标排序

然后扫描线,每到一个询问就把所有Z<=它的修改都加入

树状数组套Treap维护

时间复杂度$O(n\log^3n)$

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define N 600010
using std::sort;
int n,m,Q,i,j,x,y,z,r,t1,t2,fin[N],L[N],li,k,q[N],t,pos[N],T,C,D,ans;
char ch;
struct P{
int x1,y1,x2,y2,z,t,id;
P(){}
P(int _x1,int _y1,int _x2,int _y2,int _z,int _t,int _id){x1=_x1,y1=_y1,x2=_x2,y2=_y2,z=_z,t=_t,id=_id;}
}a[N],b[N],c[N];
struct node{
int p,val,v,sum;node*l,*r;
node(){val=v=sum=p=0;l=r=NULL;}
inline void up(){sum=v+l->sum+r->sum;}
}*blank=new(node),*bit[N],pool[N<<1],*cur=pool;
inline void Rotatel(node*&x){node*y=x->r;x->r=y->l;x->up();y->l=x;y->up();x=y;}
inline void Rotater(node*&x){node*y=x->l;x->l=y->r;x->up();y->r=x;y->up();x=y;}
void Ins(node*&x){
if(x==blank){
x=cur++;x->val=C;x->l=x->r=blank;x->v=x->sum=D;x->p=std::rand();
return;
}
x->sum+=D;
if(C==x->val){x->v+=D;return;}
if(C<x->val){
Ins(x->l);
if(x->l->p>x->p)Rotater(x);
}else{
Ins(x->r);
if(x->r->p>x->p)Rotatel(x);
}
}
void Ask(node*&x,int a,int b){
if(x==blank)return;
if(C<=a&&b<=D){ans+=x->sum;return;}
if(C<=x->val&&x->val<=D)ans+=x->v;
if(C<x->val)Ask(x->l,a,x->val-1);
if(D>x->val)Ask(x->r,x->val+1,b);
}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline int lower(int x){
int l=1,r=k,t,mid;
while(l<=r)if(L[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
return t;
}
inline bool cmp(P a,P b){return a.z<b.z;}
inline void add(int x){for(;x<=k;Ins(bit[x]),x+=x&-x)if(pos[x]<T)pos[x]=T,bit[x]=blank;}
inline int sum(int x){for(ans=0;x;x-=x&-x)if(pos[x]==T)Ask(bit[x],0,10000000);return ans;}
void solve(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
solve(l,mid),solve(mid+1,r);
for(t1=0,i=l;i<=mid;i++)if(!a[i].id)b[++t1]=a[i];
for(t2=0,i=r;i>mid;i--)if(a[i].id)c[++t2]=a[i];
if(!t1||!t2)return;
sort(b+1,b+t1+1,cmp),sort(c+1,c+t2+1,cmp);
for(T++,cur=pool,i=j=1;i<=t2;i++){
while(j<=t1&&b[j].z<=c[i].z)C=b[j].y1,D=b[j].t,add(b[j].x1),j++;
C=c[i].y1,D=c[i].y2,fin[c[i].id]+=c[i].t*(sum(c[i].x2)-sum(c[i].x1-1));
}
}
int main(){
blank->l=blank->r=blank;
read(n);
while(n--)read(x),read(y),read(z),a[++m]=P(x,y,x,y,z,1,0);
read(n);
for(i=1;i<=n;i++){
while(!(((ch=getchar())=='A')||(ch=='Q')||(ch=='C')));
if(ch=='A')read(x),read(y),read(z),a[q[++t]=++m]=P(x,y,x,y,z,1,0);
if(ch=='C'){
while((ch=getchar())!='L');
a[++m]=a[q[t--]],a[m].t=-1;
}
if(ch=='Q')read(x),read(y),read(z),read(r),a[++m]=P(x,y,x+r,y+r,z+r,1,++Q),a[++m]=P(x,y,x+r,y+r,z-1,-1,Q);
}
for(i=1;i<=m;i++)L[++li]=a[i].x1,L[++li]=a[i].x2;
sort(L+1,L+li+1);
for(i=1;i<=li;i++)if(i==1||L[i-1]!=L[i])L[++k]=L[i];
for(i=1;i<=m;i++)a[i].x1=lower(a[i].x1),a[i].x2=lower(a[i].x2);
solve(1,m);
for(i=1;i<=Q;i++)printf("%d\n",fin[i]);
return 0;
}

  

BZOJ3290 : Theresa与数据结构的更多相关文章

  1. 【kd-tree】bzoj3290 Theresa与数据结构

    离线所有操作,对所有可能存在的点建立kd-tree,add相当于权值+1,cancel相当于权值-1. 修改操作要记录kd-tree上每个点的fa,从底向上地进行修改. 优化:若一个矩形框的sumv= ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  4. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  5. 深入浅出Redis-redis底层数据结构(上)

    1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...

  6. 算法与数据结构(十五) 归并排序(Swift 3.0版)

    上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...

  7. 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)

    本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...

  8. 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找

    今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...

  9. 算法与数据结构(八) AOV网的关键路径

    上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...

随机推荐

  1. http://backboneconf.com/ @前端 真好

    http://backboneconf.com/ @前端http://backboneconf.com/ @前端http://backboneconf.com/ @前端http://backbonec ...

  2. Leetcode 之Validate Binary Search Tree(53)

    判断是否是有效的二叉搜索树,即左子树的值小于根结点,右子树的值大于根结点.可以采用递归的方式来完成,递归时如何 传递有效的参数与根结点进行比较,是此题的难点. bool isValidBST(Tree ...

  3. Nth to Last Node in List

    Find the nth to last element of a singly linked list. The minimum number of nodes in list is n. Exam ...

  4. 【转】Mybatis/Ibatis,数据库操作的返回值

    该问题,我百度了下,根本没发现什么有价值的文章:还是看源代码(详见最后附录)中的注释,最有效了!insert,返回值是:新插入行的主键(primary key):需要包含<selectKey&g ...

  5. Java for LeetCode 033 Search in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...

  6. Heap:左式堆的应用例(任意序列变单调性最小价值)

    首先来说一下什么是左式堆: A:左式堆是专门用来解优先队列合并的麻烦(任意二叉堆的合并都必须重新合并,O(N)的时间). 左式堆的性质: 1.定义零路经长:节点从没有两个两个儿子节点的路经长,把NUL ...

  7. 【USACO】checker

    一看题目 经典的8皇后问题 不过是皇后数量可变而已 不用想 回溯法. 需要个生成每次可选择序列的函数, 在存储可选择的序列时按照先大后小的顺序排的.这样每次找最小和去掉最小都很方便,只要有个记录数量的 ...

  8. ionic添加admob广告教程

    1.在你的ionic项目中使用如下命令添加admob插件: cordova plugin add cordova-plugin-admobpro 2.添加完成后,在$ionicPlatform.rea ...

  9. window常用软件

    ftpserver QQ asc pan 屏保 view putty 迅雷 teamviewer绿色 teamviewer单文件 魔方 chrome winscp WinRAR xshell 鲁大师 ...

  10. Animation & Property Animation 使用

    本篇主要讲Animation 和 Property Animation的使用,最后会讲QQ管家桌面火箭作为例子: 在Android中开发动效有两套框架可以使用,分别为 Animation 和 Prop ...