BZOJ 3153 Sone1
题解:水水哒AAA树啦
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
#define CH for(int d=0;d<=1;d++) if(ch[d])
using namespace std;
const int maxn=+,inf=-1u>>;
struct info{int mi,mx,siz,sm;}null=(info){inf,-inf,,};
struct tag{int mul,add;bool empty(){return (mul==&&add==);}}nulltag=(tag){,};
info operator+(const info&a,const info&b){
return (info){min(a.mi,b.mi),max(a.mx,b.mx),a.siz+b.siz,a.sm+b.sm};
}
info operator+(const info&a,const tag&b){
return a.siz?(info){a.mi*b.mul+b.add,a.mx*b.mul+b.add,a.siz,a.sm*b.mul+b.add*a.siz}:null;
}
tag operator+(const tag&a,const tag&b){
return (tag){a.mul*b.mul,a.add*b.mul+b.add};
}
struct snode{
snode*ch[],*fa;
info x,sm;tag od,all;
void init(){x=sm=null;od=all=nulltag;ch[]=ch[]=fa=NULL;return;}
snode(){x=sm=null;od=all=nulltag;ch[]=ch[]=fa=NULL;}
void addt(tag a){
od=od+a;all=all+a;x=x+a;sm=sm+a;return;
}
void down(){
if(!od.empty()){CH{ch[d]->addt(od);};od=nulltag;}return;
}
void update(){
sm=x;CH{sm=sm+ch[d]->sm;}return;
}
}Splay[maxn],*root[maxn];
int parent(snode*x,snode*&y){return (y=x->fa)?y->ch[]==x?:y->ch[]==x?:-:-;}
void rotate(snode*x){
snode*y,*z;int d1=parent(x,y),d2=parent(y,z);
if(y->ch[d1]=x->ch[d1^]) y->ch[d1]->fa=y;
y->fa=x;x->fa=z;x->ch[d1^]=y;
if(d2!=-) z->ch[d2]=x;
y->update();return;
}
void pushdown(snode*x){
static snode*s[maxn];int top=;
for(snode*y;;x=y){
s[top++]=x;y=x->fa;
if(!y||(y->ch[]!=x&&y->ch[]!=x)) break;
} while(top--) s[top]->down();return;
}
snode*splay(snode*x){
pushdown(x);snode*y,*z;int d1,d2;
while(true){
if((d1=parent(x,y))<) break;
if((d2=parent(y,z))<){rotate(x);break;}
if(d1==d2) rotate(y),rotate(x);
else rotate(x),rotate(x);
} x->update();return x;
}
snode*join(snode*x,snode*y){
if(!x)return y;if(!y)return x;
while(x->ch[]) x->down(),x=x->ch[];
splay(x)->ch[]=y;y->fa=x;x->update();return x;
}
struct node{
node*ch[],*fa,*s[];
info x,sm,sb,all;tag cha,tre;bool rev;
int id;
void revt(){
swap(ch[],ch[]);swap(s[],s[]);rev^=;return;
}
void chat(tag a){
x=x+a;sm=sm+a;cha=cha+a;all=sm+sb;return;
}
void tret(tag a){
tre=tre+a;sb=sb+a;all=sm+sb;if(root[id])root[id]->addt(a);return;
}
void down(){
if(rev){CH{ch[d]->revt();}rev=false;}
if(!cha.empty()){CH{ch[d]->chat(cha);}cha=nulltag;}
if(!tre.empty()){CH{ch[d]->tret(tre);}tre=nulltag;}
return;
}
void update(){
sm=x;sb=null;
if(root[id])sb=sb+root[id]->sm;
CH{sm=sm+ch[d]->sm;sb=sb+ch[d]->sb;}
all=sm+sb;
s[]=ch[]?ch[]->s[]:this;
s[]=ch[]?ch[]->s[]:this;
return;
}
}lct[maxn];
int parent(node*x,node*&y){return (y=x->fa)?y->ch[]==x?:y->ch[]==x?:-:-;}
void rotate(node*x){
node*y,*z;int d1=parent(x,y),d2=parent(y,z);
if(y->ch[d1]=x->ch[d1^]) y->ch[d1]->fa=y;
y->fa=x;x->fa=z;x->ch[d1^]=y;
if(d2!=-) z->ch[d2]=x;
y->update();return;
}
void pushdown(node*x){
static node*s[maxn];int top=;
for(node*y;;x=y){
s[top++]=x;y=x->fa;
if(!y||(y->ch[]!=x&&y->ch[]!=x)) break;
} while(top--) s[top]->down();return;
}
node*splay(node*x){
pushdown(x);node*y,*z;int d1,d2;
while(true){
if((d1=parent(x,y))<) break;
if((d2=parent(y,z))<){rotate(x);break;}
if(d1==d2) rotate(y),rotate(x);
else rotate(x),rotate(x);
} x->update();return x;
}
void detach(node*x){
snode*p=x->ch[]->s[]->id+Splay;p->init();
p->x=x->ch[]->all;x->ch[]=NULL;
int id=x->id;
p->ch[]=root[id];
if(root[id]) root[id]->fa=p;
p->update();root[id]=p;return;
}
void connect(node*x,node*y){
snode*p=y->s[]->id+Splay;
int id=x->id;splay(p);
if(p->ch[]) p->ch[]->fa=NULL;
if(p->ch[]) p->ch[]->fa=NULL;
root[id]=join(p->ch[],p->ch[]);
y->chat(p->all);y->tret(p->all);return;
}
node*access(node*x){
node*ret=NULL;
for(;x;x=x->fa){
splay(x);if(x->ch[]) detach(x);
x->ch[]=ret;if(ret) connect(x,ret);
(ret=x)->update();
} return ret;
}
void makeroot(int x){access(x+lct)->revt();return;}
void link(int x,int y){
makeroot(x);splay(lct+x)->fa=lct+y;
access(lct+y);splay(lct+y)->ch[]=lct+x;
return;
}
void changesub(int x,int y,tag t){
makeroot(x);access(lct+y);splay(lct+y);
lct[y].x=lct[y].x+t;
if(root[y]) root[y]->addt(t);
lct[y].update();return;
}
void changecha(int x,int y,tag t){
makeroot(x);access(lct+y)->chat(t);return;
}
info querycha(int x,int y){
makeroot(x);return access(lct+y)->sm;
}
info querysub(int x,int y){
makeroot(x);access(lct+y);splay(lct+y);return root[y]?lct[y].x+root[y]->sm:lct[y].x;
}
int treeroot;
void cutfa(int x){
node*t=(access(lct+x),splay(lct+x));
t->ch[]=t->ch[]->fa=NULL;t->update();return;
}
void linkfa(int x,int fa){
access(fa+lct);splay(lct+fa);
makeroot(x);splay(lct+x)->fa=lct+fa;lct[fa].update();
snode*p=Splay+x;p->init();p->x=lct[x].all;
p->ch[]=root[fa];if(root[fa]) root[fa]->fa=p;
root[fa]=p;p->update();return;
}
void splitfa(int r,int x,int fa){
makeroot(r);if((access(lct+x),access(lct+fa))==lct+x) return;
cutfa(x);linkfa(x,fa);return;
}
int n,Q,p1[maxn],p2[maxn],A[maxn];
void inittree(int*a){
for(int i=;i<=n;i++){
lct[i].id=i;
lct[i].s[]=lct[i].s[]=lct+i;
lct[i].x=lct[i].sm=lct[i].all=(info){a[i],a[i],,a[i]};
lct[i].cha=lct[i].tre=nulltag;
} return;
}
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')sig=-;ch=getchar();}
while(isdigit(ch))x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
void init(){
n=read();Q=read();
for(int i=;i<=n;i++) p1[i]=read(),p2[i]=read();
for(int i=;i<=n;i++) A[i]=read();
inittree(A);
for(int i=;i<=n;i++) link(p1[i],p2[i]);
treeroot=read();makeroot(treeroot);
return;
}
void work(){
int x,y,z,tp;
while(Q--){
tp=read();x=read();
if(tp==) y=read(),changesub(treeroot,x,(tag){,y});
else if(tp==) makeroot(x),treeroot=x;
else if(tp==) y=read(),z=read(),changecha(x,y,(tag){,z});
else if(tp==) write(querysub(treeroot,x).mi),ENT;
else if(tp==) write(querysub(treeroot,x).mx),ENT;
else if(tp==) y=read(),changesub(treeroot,x,(tag){,y});
else if(tp==) y=read(),z=read(),changecha(x,y,(tag){,z});
else if(tp==) y=read(),write(querycha(x,y).mi),ENT;
else if(tp==) y=read(),write(querycha(x,y).mx),ENT;
else if(tp==) y=read(),splitfa(treeroot,x,y);
else if(tp==) y=read(),write(querycha(x,y).sm),ENT;
else if(tp==) write(querysub(treeroot,x).sm),ENT;
}
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}
BZOJ 3153 Sone1的更多相关文章
- bzoj 3153: Sone1 Toptree
3153: Sone1 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 511 Solved: 202[Submit][Status][Discuss ...
- 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 ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- Object-C 点语法 -- 笔记
第一种是经典方式, 第一种是点语法.
- Java线程的相关方法
~ start() 启动线程方法 ~ run() 调用start()方法时,真正执行的就是该方法的方法体 ~ sleep() 让当前线程睡眠,睡眠到期自动苏醒,并进入可运行状态,而不是运行状态 ...
- 【移动开发】Android中将我们平时积累的工具类打包
Android开发的组件打包成JAR安装包,通过封闭成JAR包,可以重复利用,非常有利于扩展和减少工作重复性.这里为了讲解方便,我用了之前的一个代码框架中核心部分,不了解的可以回头看一下:http:/ ...
- NYOJ 980 格子刷油漆 动态规划
这道题目状态转移方程比较复杂,刚开始以为没这么多情况,看了好多大牛的博客再加上与同学讨论才看懂,写下心得. 因为起点不固定,所以我们一个一个来考虑,先从角上考虑,设三个数组来表示分别为D,A,Sum, ...
- canvas在手机qq浏览器显示错乱
做大转盘的时候,使用html5 canvas 生成转盘,但在手机qq浏览器中显示错乱. 原本想在后台生成大转盘图片,后来想一想既然用图片来实现, 还不如直接由canvas 导出 toDataURL 在 ...
- mysql explain 命令解释
转载http://bzyyc.happy.blog.163.com/blog/static/6143064720115102551554/ key实 际使用的索引.如果为NULL,则没有使用索引.很少 ...
- Debugging Failed Because Integrated Windows Authentication Is Not Enabled
To enable integrated Windows authentication Log onto the Web server using an administrator account. ...
- UITableView初始
近期在自学IOS,看了黑马提供的视频,讲的很好.在此做些笔记,以供以后查阅.注明了知识来源应该不算侵权吧. 一 UITableView 1,数据展示的条件 1⃣️ UITableView的所有数据都是 ...
- 查询数据库返回List<Entity>问题
如果判断所返回的List<Entity>是否为空不能用 list!=null,因为如果查询数据为空则会返回[],当与null判断的时候会判断为有数据,此时判断条件应该写成list.size ...
- 单点登录CAS使用记(二):部署CAS服务器以及客户端
CAS-Server下载地址:https://www.apereo.org/projects/cas/download-cas CAS-Client下载地址:http://developer.jasi ...