Description

 小C正在出一道题...因为语文水平有限他想不出复杂的背景,所以以下就是题意了。
  平面上有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表示点数。
  接下来N行,每行3个整数分别表示Pi的坐标与权值。
  接下来一个整数Q表示操作数。
  接下来Q行,每行描述一个操作,格式如上所述。

Output

  对于每个Q操作,输出三个整数,依次表示询问集合权值的最大值,最小值与和。
预处理出点集的一颗二维k-d tree
将每个点到根的路径复制出来作为初始状态
由于树形态相同,合并和分裂可以仿照线段树
分裂时增加的点数$T(n)=2T(\frac{n}{4})+O(1)=O(\sqrt{n})$
合并复杂度与减少的点数同阶
因此总时间复杂度$O(q\sqrt{n})$
由每个点到根的路径长度之和可得空间复杂度的上界$O(nlogn)$
#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的更多相关文章

  1. bzoj AC倒序

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

  2. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  3. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  4. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  5. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  6. 关于TCP中的MSS

    MSS 是TCP选项中最经常出现,也是最早出现的选项.MSS选项占4byte.MSS是每一个TCP报文段中数据字段的最大长度,注意:只是数据部分的字段,不包括TCP的头部.TCP在三次握手中,每一方都 ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. 【postman】谷歌postman插件的基本选项含义

    1.form-data:  就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开.既可以上传键值对,也可以上传文件.当上传的字段是文件 ...

  2. Gym 101246D Fire in the Country(dfs求SG函数)

    http://codeforces.com/gym/101246/problem/D 题意: 给定一个无向有环图,大火从1点开始,每个时间点与它相邻的点也将会着火,现在有两个人轮流操作机器人,机器人从 ...

  3. nginx.conf 配置详解

    目录 pid user error_log worker_connections include http server nginx主配置文件中的内容 pid 主线程id的存储位置. # cat /u ...

  4. RJ45接口

    什么是rj45接口? rj45是各种不同接头的一种类型,通常用于数据传输,最常见的应用为网卡接口. 常见的RJ45接口有两类:用于以太网网卡.路由器以太网接口等的DTE类型,还有用于交换机等的DCE类 ...

  5. hdu1564博弈+找规律

    #include<map> #include<set> #include<cmath> #include<queue> #include<stac ...

  6. 047——VUE中css过渡动作实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. HDU 1069 Monkey and Banana 基础DP

    题目链接:Monkey and Banana 大意:给出n种箱子的长宽高.每种不限个数.可以堆叠.询问可以达到的最高高度是多少. 要求两个箱子堆叠的时候叠加的面.上面的面的两维长度都严格小于下面的. ...

  8. VERSIONINFO Resource

    转自(http://www.xuebuyuan.com/1202062.html) VERSIONINFO Resource Defines a version-information resourc ...

  9. sql 时间段内没有的数据等于0

    如何实现没有的时间段中使用0来填充?? if object_id('[A]') is not null drop table [A] go create table [A]([日期] datetime ...

  10. T4 模板代码生成

    <# //********************************************************* // // Copyright (c) Microsoft. All ...