bzoj 3615: MSS
Description
平面上有N个点,开始时每个点属于一个不同的集合。不妨设点Pi属于集合Si。请维护数据结构支持以下三种操作:
"Merge x y":将集合Sy中的点到Sx中;
"Split i d v"(d ∈ {0, 1}):创建新集合Sc + 1,Sc + 2,之后将集合Si中的所有点中,第d维坐标不超过v的到集合Sc + 1中,超过v的移动到集合Sc + 2中,其中c为现有集合数( 包括之前合并和分割中产生的空集 );
"Query i":查询集合Si中点权值的最大值,最小值及和;
"Add i d":将集合Si中所有点的权值增加d。
方便起见,对于d ∈ {0, 1},输入的所有点的第d维坐标不重复。所有操作涉及的集合非空。
Input
接下来N行,每行3个整数分别表示Pi的坐标与权值。
接下来一个整数Q表示操作数。
接下来Q行,每行描述一个操作,格式如上所述。
Output
#include<bits/stdc++.h>
#define G getchar()
int _(){
int x=,f=,c=G;
while(c<)c=='-'&&(f=-),c=G;
while(c>)x=x*+c-,c=G;
return x*f;
}
int _s(){
int c=G,c0;
while(c<)c=G;
c0=c;
while(c>)c=G;
return c0;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
const int N=,inf=0x3f3f3f3f;
int n,qp;
struct node;
node*newnode();
struct node{
node*c[];
int mn[],mx[];
int mnv,mxv,sz,id;
long long sum,a;
void add(long long x){
if(this){
a+=x;
mnv+=x;
mxv+=x;
sum+=x*sz;
}
}
void dn(){
if(a){
c[]->add(a);
c[]->add(a);
a=;
}
}
void up(){
mnv=inf;mxv=-inf;sum=;
sz=;
if(c[]){
mnv=c[]->mnv;
mxv=c[]->mxv;
sum=c[]->sum;
sz=c[]->sz;
}
if(c[]){
mnv=min(mnv,c[]->mnv);
mxv=max(mxv,c[]->mxv);
sum+=c[]->sum;
sz+=c[]->sz;
}
}
void set(int x0,int x1,int v){
mn[]=mx[]=x0;
mn[]=mx[]=x1;
sum=mnv=mxv=v;
sz=;a=;
}
void query(){
printf("%d %d %lld\n",mxv,mnv,sum);
}
void upds(){
for(int i=;i<;++i){
mn[i]=min(c[]->mn[i],c[]->mn[i]);
mx[i]=max(c[]->mx[i],c[]->mx[i]);
}
}
}mem[N*],*pool[N*],*rt0,*n0[N],*rts[N*];
int pp;
node*newnode(){
return pool[--pp];
}
int dx=;
bool cmp(node*a,node*b){
return a->mn[dx]<b->mn[dx];
}
node*build(int L,int R){
if(L==R)return n0[L];
int M=(L+R)>>;
std::nth_element(n0+L,n0+M,n0+R+,cmp);
node*w=newnode();
dx^=;
w->c[]=build(L,M);
w->c[]=build(M+,R);
w->upds();
dx^=;
return w;
}
node*ss[];
int sp=;
void init(node*w){
ss[sp++]=w;
if(w->id){
node*t=w;
for(int i=sp-;~i;--i){
node*u=newnode();
*u=*ss[i];
int d=u->c[]==ss[i+];
u->c[d]=t;
u->c[d^]=;
u->up();
t=u;
}
rts[w->id]=t;
}else{
init(w->c[]);
init(w->c[]);
}
--sp;
}
int _x,_d;
void split(node*w,node*&l,node*&r){
if(!w)l=r=;
else if(_x<w->mn[_d])l=,r=w;
else if(w->mx[_d]<=_x)l=w,r=;
else{
w->dn();
node*u=newnode();
*u=*w;
split(w->c[],w->c[],u->c[]);
split(w->c[],w->c[],u->c[]);
w->up();u->up();
l=w,r=u;
}
}
node*merge(node*a,node*b){
if(!a)return b;
if(!b)return a;
a->dn();b->dn();
a->c[]=merge(a->c[],b->c[]);
a->c[]=merge(a->c[],b->c[]);
a->up();
pool[pp++]=b;
return a;
}
int main(){
n=_();
pp=n*;
for(int i=;i<pp;++i)pool[i]=mem+i;
for(int i=,x,y;i<=n;++i){
x=_();y=_();
n0[i]=newnode();
n0[i]->set(x,y,_());
n0[i]->id=i;
}
rt0=build(,n);
init(rt0);
for(qp=_();qp;--qp){
int o=_s();
if(o=='M'){
int x=_(),y=_();
rts[x]=merge(rts[x],rts[y]);
rts[y]=;
}else if(o=='S'){
int x=_();
_d=_();_x=_();
split(rts[x],rts[n+],rts[n+]);
rts[x]=;
n+=;
}else if(o=='Q'){
rts[_()]->query();
}else{
int x=_();
rts[x]->add(_());
}
}
return ;
}
bzoj 3615: MSS的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- 关于TCP中的MSS
MSS 是TCP选项中最经常出现,也是最早出现的选项.MSS选项占4byte.MSS是每一个TCP报文段中数据字段的最大长度,注意:只是数据部分的字段,不包括TCP的头部.TCP在三次握手中,每一方都 ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- awk根据指定的字符串分割字符串
以从字符串"hello-kitty-red-for-you"中获取-for前面的内容为例: echo "hello-kitty-red-for-you" |aw ...
- Intellij IDEA 创建控制台项目,断点调试快捷方式
在idea 2016中创建一个控制台项目(经常会忘) 打开创建界面 注意,什么都不要选,点击next(最坑的地方,经常忘) 再次点击next ============================= ...
- 解决 E: Could not get lock /var/lib/apt/lists/lock
参考:Unable to lock the administration directory (/var/lib/dpkg/) is another process using it? 在更换软件源时 ...
- 调用libpci库出现的问题和解决方法
调用libpci库出现的问题和解决方法 本方案以pciutils-3.5.1为例. 1. 从以下地址下载pciutils-3.5.1.tar.xz https://www.kernel.org ...
- JavaScript获取输入框内容
html: <input name="money" type="number" placeholder="税前工资"><b ...
- 使用向量化的 if:ifelse
进行分支计算的一个替代方法是 ifelse( ).这个函数接收一个逻辑向量作为判定条件,并且返回一个向量.对于逻辑判定条件内的每一个元素,若是 TRUE,则选择第 2个参数 yes 中所对应的元素:若 ...
- log模块和report模块
这两个模块不需要管,我们生成的log和report直接添加到这里就好
- 将java打jar包成linux后台服务service
将java打jar包成linux后台服务service 第一步:将java程序打成jar包 build.gradle配置文件中加spring-boot-gradle-plugin插件,具体配置如下(配 ...
- Qt 线程基础
(转自:http://my.oschina.net/laopiao/blog/88158) 何谓线程? 线程与并行处理任务息息相关,就像进程一样.那么,线程与进程有什么区别呢?当你在电子表格上进行数据 ...
- 返回值为 Record类型的函数 初始化 Result
function TMiTeC_Storage.GetPhysInfo(Index: integer): TDeviceInfo; begin Finalize(Result); FillChar(R ...