题解:水水哒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的更多相关文章

  1. bzoj 3153: Sone1 Toptree

    3153: Sone1 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 511  Solved: 202[Submit][Status][Discuss ...

  2. bzoj AC倒序

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

  3. BZOJ 2127: happiness [最小割]

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

  4. BZOJ 3275: Number

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

  5. BZOJ 2879: [Noi2012]美食节

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

  6. bzoj 4610 Ceiling Functi

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

  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. fsck 修复ext3文件系统(用于linux系统时间不对,文件系统信息有错引起的die with exit status等的一些问题)

    有时候我们用虚拟机装了linux,可是我们做开发的人员,系统时间可能出于一些特殊要求调整过(例如保持一些特殊软件不过期,需要锁定时间等等),这样linux的系统时间久不准了,如果时间不准,会造成ext ...

  2. Linux内核-内核线程

    线程分类:内核线程.用户线程(指不需要内核支持而完全建立在用户空间的线程库,这种线程效率高,由于Linux内核没有轻量级进程(线程)的概念,因此不能独立的对用户线程进行调度,而是由一个线程运行库来组织 ...

  3. 字体在Android View中的输出 drawText

    Canvas 作为绘制文本时,使用FontMetrics对象,计算位置的坐标.   public static class FontMetrics {               public flo ...

  4. Brunch:快捷的HTML5构建工具

    Brunch,一个超快的HTML5构建工具.它可以(官方介绍): 编译你的脚本,模板,样式,链接它们, 将脚本和模板封装进common.js/AMD模块里,链接脚本和样式, 为链接文件生成源地图,复制 ...

  5. COM编程入门第二部分——深入COM服务器

    本文为刚刚接触COM的程序员提供编程指南,解释COM服务器内幕以及如何用C++编写自己的接口.继上一篇COM编程入门之后,本文将讨论有关 COM服务器的内容,解释编写自己的COM接口和COM服务器所需 ...

  6. [Angular 2] Passing Observables into Components with Async Pipe

    The components inside of your container components can easily accept Observables. You simply define ...

  7. 怎样将关系型数据表转换至hbase数据表

    首先须要把关系型数据库的数据表的数据添加由 "纵向延伸",转变为HBase数据表的"横向延伸" 一.Hbase的存储结构 a)      HBase以表(HTa ...

  8. apk文件伪装zip64格式案例

    软件样本:http://files.cnblogs.com/files/mmmmar/FMRMemoryCleaner.apk 在论坛看在网友求助把一个小的app去广告,下载一看是清理内存的,刚开始让 ...

  9. 超好用文件对比工具 – Beyond Compare

    超好用文件对比工具 – Beyond Compare,开发中文件.目录对比神器,有了它,再也不用为找不到修改的内容而发愁了. 具备的丰富实用功能: 并列比较文件夹.FTP 网站或 Zip 文件: 为以 ...

  10. 关于apache下同IP多域名支持HTTPS和80跳转HTTPS的配置

    httpd-ssl的配置: Listen 443 NameVirtualHost *:443 AddType application/x-x509-ca-cert .crt AddType appli ...