題目
這題之前叫睡覺困難綜合徵。
首先咱們須要知道起牀困難綜合徵怎麼作。
大概就是先用一個全\(0\)和全\(1\)的變量跑一遍處理出每一位\(1\)和\(0\)最後會變成什麼。
而後高位貪心:若是當前位可以從\(0\)到\(1\),那麼直接選上。若是可以從\(1\)到\(0\),那麼能選就選。
如今咱們把它放到了樹上。
那麼使用LCT或者樹剖就能夠解決了。node
#include<bits/stdc++.h> #define N 100007 #define ull unsigned long long using namespace std; namespace IO { char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[22],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21); char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); } void Flush() { fwrite(obuf,1,oS-obuf,stdout),oS=obuf; } void Put(char x) { *oS++=x; if(oS==oT) Flush(); } ull read(){ull x=0;char ch=Get();while(ch>'9'||ch<'0')ch=Get();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=Get();return x;} void write(ull x){int top=0;if(!x)return (void)Put('0'),Put('\n');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('\n');} } using namespace IO; struct node{ull f0,f1;}val[N],lr[N],rl[N]; node merge(node x,node y){return (node){(~x.f0&y.f0)|(x.f0&y.f1),(~x.f1&y.f0)|(x.f1&y.f1)};} int fa[N],ch[N][2],r[N]; #define lc ch[p][0] #define rc ch[p][1] int nroot(int p){return ch[fa[p]][0]==p||ch[fa[p]][1]==p;} void pushup(int p) { lr[p]=rl[p]=val[p]; if(lc) lr[p]=merge(lr[lc],lr[p]),rl[p]=merge(rl[p],rl[lc]); if(rc) lr[p]=merge(lr[p],lr[rc]),rl[p]=merge(rl[rc],rl[p]); } void pushrev(int p){swap(lr[p],rl[p]),swap(lc,rc),r[p]^=1;} void pushdown(int p){if(r[p])pushrev(lc),pushrev(rc),r[p]=0;} void pushall(int p){if(nroot(p))pushall(fa[p]);pushdown(p);} void rotate(int p) { int x=fa[p],y=fa[x],k=ch[x][1]==p,w=ch[p][!k]; if(nroot(x)) ch[y][ch[y][1]==x]=p; ch[p][!k]=x,ch[x][k]=w,fa[w]=x,fa[x]=p,fa[p]=y,pushup(x); } void splay(int p) { pushall(p); for(int x;nroot(p);rotate(p))if(nroot(x=fa[p])) rotate((ch[x][0]==p)^(ch[fa[x]][0]==x)? p:x); pushup(p); } void access(int p){for(int x=0;p;p=fa[x=p])splay(p),rc=x,pushup(p);} void makeroot(int p){access(p),splay(p),pushrev(p);} void split(int u,int v){makeroot(u),access(v),splay(v);} void link(int u,int v){makeroot(u),fa[u]=v;} ull query(ull w,int v,int u) { ull ans=0,tmp=1;split(u,v); for(int k=63;~k;--k) if(lr[v].f0&(tmp<<k)) ans+=(tmp<<k); else if(lr[v].f1&(tmp<<k)&&w>=(tmp<<k)) w-=(tmp<<k),ans+=(tmp<<k); return ans; } int main() { int n=read(),m=read(),i,u,v;read(); ull e=0,x; for(i=1;i<=n;++i) switch(read()) { case 1:val[i]=(node){e,read()};break; case 2:val[i]=(node){read(),~e};break; case 3:x=read(),val[i]=(node){x,~x};break; } for(i=1;i<n;++i) u=read(),v=read(),link(u,v); while(m--) { if(read()==1) write(query(read(),read(),read())); else { u=read(); switch(read()) { case 1:val[u]=(node){e,read()};break; case 2:val[u]=(node){read(),~e};break; case 3:x=read(),val[u]=(node){x,~x};break; } splay(u); } } return Flush(),0; }