AC这道超级工业题留念
由于并不能支持子树操作,所以有了这种神奇的数据结构
好像实际上是叫树
我也不清楚实际上和有啥区别…
大致思想就是在上每个节点个儿子变成四个儿子
多的2个作为另外一颗的根的左右儿子
这个用来维护所有虚儿子
于是子树操作就可以在这个上打标记啦
由于各个儿子之间没有大小关系,所以必须全部设在叶子节点,其他点相当于是虚点
据说有的常数
而且不知道为什么
肯定是太naiive而且没有丰富的人生经验
导致里信息维护错了之类的奇怪的问题
要在不必要(雾)的地方加一些东西才能过
比如最后得
之后要之类的
已经放弃治疗了
具体实现可以看的博客
代码:
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
#define poly vector<int>
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int inf=1<<30;
struct tag{
int mul,add;
tag(){mul=1,add=0;}
tag(int _m,int _a){mul=_m,add=_a;}
inline bool empty(){return mul==1&&!add;}
friend inline tag operator +(cs tag &a,cs tag &b){
return tag(a.mul*b.mul,b.mul*a.add+b.add);
}
void operator +=(cs tag &a){*this=*this+a;}
inline int calc(int x){return x*mul+add;}
};
struct node{
int s,mn,mx,siz;
node(){s=siz=0,mn=inf,mx=-inf;}
node(int x){s=mn=mx=x,siz=1;}
node(int _s,int _mn,int _mx,int _siz){s=_s,mn=_mn,mx=_mx,siz=_siz;}
friend inline node operator +(cs node &a,cs node &b){
return node(a.s+b.s,min(a.mn,b.mn),max(a.mx,b.mx),a.siz+b.siz);
}
void operator +=(cs node &a){*this=*this+a;}
friend inline node operator +(cs node &a,tag b){
return a.siz?node(a.s*b.mul+a.siz*b.add,b.calc(a.mn),b.calc(a.mx),a.siz):a;
}
void operator +=(tag a){*this=*this+a;}
};
int rt;
cs int N=200005;
namespace AT{
int fa[N],son[N][4],stk[N],top,rev[N],in[N],val[N],tot;
node sc[N],st[N],sa[N];
tag ct[N],tt[N];
#define lc(u) son[u][0]
#define rc(u) son[u][1]
#define pc(u) son[u][2]
#define qc(u) son[u][3]
inline void delet(int u){
stk[++top]=u;
lc(u)=rc(u)=pc(u)=qc(u)=rev[u]=in[u]=val[u]=fa[u]=0;
}
inline int newnode(){
int u=top?stk[top--]:++tot;
in[u]=1;return u;
}
inline void initnode(int u,int k){
st[u]=node(),sa[u]=sc[u]=node(k),val[u]=k;
}
inline bool isrt(int u,int t){
if(!fa[u])return 1;
if(t)return !in[u]||!in[fa[u]];
return (lc(fa[u])!=u&&rc(fa[u])!=u)||in[fa[u]]||in[u];
}
inline void pushrev(int u){
swap(lc(u),rc(u)),rev[u]^=1;
}
inline void pushnowc(int u,tag k){
sc[u]+=k,sa[u]=sc[u]+st[u];
val[u]=k.calc(val[u]),ct[u]+=k;
}
inline void pushnowt(int u,tag k,int t){
st[u]+=k,tt[u]+=k;
if(!in[u]&&t)pushnowc(u,k);
else sa[u]=sc[u]+st[u];
}
inline void pushdown(int u){
if(rev[u]){
if(lc(u))pushrev(lc(u));
if(rc(u))pushrev(rc(u));
rev[u]=0;
}
if(!in[u]&&!ct[u].empty()){
if(lc(u))pushnowc(lc(u),ct[u]);
if(rc(u))pushnowc(rc(u),ct[u]);
ct[u]=tag();
}
if(!tt[u].empty()){
if(lc(u))pushnowt(lc(u),tt[u],0);
if(rc(u))pushnowt(rc(u),tt[u],0);
if(pc(u))pushnowt(pc(u),tt[u],1);
if(qc(u))pushnowt(qc(u),tt[u],1);
tt[u]=tag();
}
}
inline void pushup(int u){
st[u]=node();
if(lc(u))st[u]+=st[lc(u)];
if(rc(u))st[u]+=st[rc(u)];
if(pc(u))st[u]+=sa[pc(u)];
if(qc(u))st[u]+=sa[qc(u)];
if(in[u])
sc[u]=node(),sa[u]=st[u];
else{
sc[u]=node(val[u]);
if(lc(u))sc[u]+=sc[lc(u)];
if(rc(u))sc[u]+=sc[rc(u)];
sa[u]=sc[u]+st[u];
}
}
inline int posit(int u){
if(lc(fa[u])==u)return 0;
if(rc(fa[u])==u)return 1;
if(pc(fa[u])==u)return 2;
if(qc(fa[u])==u)return 3;
return 4;
}
inline void rotate(int v,int t){
int u=fa[v],pp=(son[u][t+1]==v)+t,z=fa[u],kk;
fa[v]=z;
if(z&&(kk=posit(u))!=4)son[z][kk]=v;
son[u][pp]=son[v][pp^1];
if(son[v][pp^1])fa[son[v][pp^1]]=u;
fa[u]=v,son[v][pp^1]=u;
pushup(u),pushup(v);
}
int q[N];
inline void pushall(int u,int t){
q[q[0]=1]=u;
for(int v=u;!isrt(v,t);v=fa[v])q[++q[0]]=fa[v];
for(int i=q[0];i;i--)pushdown(q[i]);
}
inline void splay(int u,int t=0){
pushall(u,t);
while(!isrt(u,t)){
if(!isrt(fa[u],t))
((son[fa[fa[u]]][t]==fa[u])^(son[fa[u]][t]==u))?rotate(u,t):rotate(fa[u],t);//????
rotate(u,t);
}pushup(u);
}
inline int getson(int u,int t){
pushdown(son[u][t]);return son[u][t];
}
inline void setson(int u,int t,int v){
son[u][t]=v,fa[v]=u;
}
inline void add(int u,int v){
if(!v)return;
pushdown(u);
if(!pc(u))return setson(u,2,v);
if(!qc(u))return setson(u,3,v);
while(pc(u)&&in[pc(u)])u=getson(u,2);
int z=newnode();
setson(z,2,pc(u));
setson(z,3,v);
setson(u,2,z);
splay(z,2);
}
inline void del(int u){
if(!u)return;
splay(u);
if(!fa[u])return;
int v=fa[u];
if(in[v]){
pushall(v,2);
int z=fa[v];
if(z)setson(z,posit(v),getson(v,posit(u)^1)),splay(z,2);
delet(v);
}
else son[v][posit(u)]=0,splay(v);
fa[u]=0;
}
inline int Fa(int u){
splay(u);
if(!fa[u])return 0;
if(!in[fa[u]])return fa[u];
int t=fa[u];
splay(fa[u],2);
return fa[t];
}
inline int access(int u){
int v=0;
for(;u;v=u,u=Fa(u)){
splay(u),del(v);
add(u,rc(u)),setson(u,1,v);
pushup(u);
}
return v;
}
inline void makert(int u){
access(u),splay(u),pushrev(u);
}
inline void link(int u,int v){
makert(u),access(v),add(v,u),access(u);
}
inline void cut(int u){
access(u),splay(u);
fa[lc(u)]=0,lc(u)=0;
pushup(u);
}
inline int Lca(int u,int v){
access(u);return access(v);
}
inline void updatec(int u,int v,tag k){
makert(u),access(v),splay(v);
pushnowc(v,k),makert(rt);
}
inline void updatet(int u,tag k){
access(u),splay(u);
val[u]=k.calc(val[u]);
if(pc(u))pushnowt(pc(u),k,1);
if(qc(u))pushnowt(qc(u),k,1);
pushup(u),splay(u);
}
inline node queryc(int u,int v){
makert(u),access(v),splay(v);
node res=sc[v];makert(rt);return res;
}
inline node queryt(int u){
access(u),splay(u);
node res=node(val[u]);
if(pc(u))res+=sa[pc(u)];
if(qc(u))res+=sa[qc(u)];
return res;
}
}
int n,m;
pii e[N];
int main(){
n=read(),m=read();
AT::tot=n;
for(int i=2;i<=n;i++)e[i].fi=read(),e[i].se=read();
for(int i=1;i<=n;i++)AT::initnode(i,read());
for(int i=2;i<=n;i++)AT::link(e[i].fi,e[i].se);
rt=read();
AT::makert(rt);
while(m--){
int op=read();
int u=read();
if(op==0){
int k=read();
AT::updatet(u,tag(0,k));
}
else if(op==1)
AT::makert(u);
else if(op==2){
int v=read(),k=read();
AT::updatec(u,v,tag(0,k));
}
else if(op==3)
cout<<AT::queryt(u).mn<<'
';
else if(op==4)
cout<<AT::queryt(u).mx<<'
';
else if(op==5){
int k=read();
AT::updatet(u,tag(1,k));
}
else if(op==6){
int v=read(),k=read();
AT::updatec(u,v,tag(1,k));
}
else if(op==7){
int v=read();
cout<<AT::queryc(u,v).mn<<'
';
}
else if(op==8){
int v=read();
cout<<AT::queryc(u,v).mx<<'
';
}
else if(op==9){
int v=read();
if(AT::Lca(u,v)==u)continue;
AT::cut(u),AT::link(v,u);
AT::makert(rt);
}
else if(op==10){
int v=read();
cout<<AT::queryc(u,v).s<<'
';
}
else cout<<AT::queryt(u).s<<'
';
}
}