题解loj146,dfs序3

  1 #include<cstdio>
  2 #define it register int
  3 #define il inline
  4 const int N=8000005;
  5 typedef long long ll;
  6 int h[N],nxt[N],adj[N],opt,l[N],r[N],s[N],id[N],root,u,v,k,d[N],n,m,fa[N],top[N],w[N],son[N],t,cnt,lc;
  7 ll ans,ww[N],c1[N],c2[N];
  8 namespace io {
  9     const int SIZE = (1 << 21) + 1;
 10     char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55];
 11     int f, qr;
 12 #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
 13     inline void flush () {
 14         fwrite (obuf, 1, oS - obuf, stdout);
 15         oS = obuf;
 16     }
 17     inline void putc (char x) {
 18         *oS ++ = x;
 19         if (oS == oT) flush ();
 20     }
 21     template<class T>
 22     inline void getc(T &x)
 23     {
 24         for(c=gc();!((c>='a'&&c<='z')||(c>='A'&&c<='Z'));c=gc());
 25         x=c;
 26     }
 27     template <class I>
 28     inline void fr (I &x) {
 29         for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
 30         for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15);
 31         x *= f;
 32     }
 33     template <class I>
 34     inline void print (I x) {
 35         if (!x) putc ('0');
 36         if (x < 0) putc ('-'), x = -x;
 37         while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
 38         while (qr) putc (qu[qr --]);
 39     }
 40     struct Flusher_ {
 41         ~Flusher_() {
 42             flush();
 43         }
 44     } io_flusher_;
 45 }
 46 using io :: fr;
 47 using io :: putc;
 48 using io :: print;
 49 using io :: getc;
 50 il void Add(){
 51     nxt[++t]=h[u],h[u]=t,adj[t]=v,nxt[++t]=h[v],h[v]=t,adj[t]=u;
 52 }
 53 il void DFS(it x){
 54     s[x]=1,d[x]=d[fa[x]]+1,l[x]=++cnt,ww[x]=w[x];
 55     for(it i=h[x];i;i=nxt[i])
 56         if(adj[i]!=fa[x]){
 57             fa[adj[i]]=x,DFS(adj[i]),s[x]+=s[adj[i]],ww[x]+=ww[adj[i]];
 58             if(s[adj[i]]>s[son[x]])
 59                 son[x]=adj[i];
 60         }
 61     r[x]=cnt;
 62 }
 63 il void dfs(it x){ 
 64     if(!top[x]) top[x]=x;
 65     if(!son[x]) return;
 66     top[son[x]]=top[x],dfs(son[x]);
 67     for(it i=h[x];i;i=nxt[i])
 68         if(adj[i]!=fa[x]&&adj[i]!=son[x]) dfs(adj[i]);
 69 }
 70 il void sp(int &p,int &q){
 71     p+=q,q=p-q,p-=q;
 72 }
 73 il void lca(){
 74     it p=u,q=v;
 75     while(top[p]!=top[q]){
 76         if(d[top[p]]<d[top[q]]) sp(p,q);
 77         p=fa[top[p]];
 78     }
 79     lc=d[p]<d[q]?p:q;
 80 }
 81 il ll cal(ll *t,it x){
 82     ll now=0;
 83     while(x) now+=t[x],x-=(x&-x);
 84     return now;
 85 }
 86 il void add(ll *t,it x,ll num){
 87     while(x<=n) t[x]+=num,x+=(x&-x);
 88 }
 89 il ll q(ll *t,it l,it r){
 90     return cal(t,r)-cal(t,l-1);
 91 }
 92 il void ins(it x){
 93     add(c1,l[x],k),add(c2,l[x],1ll*k*d[x]);
 94 }
 95 il void del(it x){
 96     add(c1,l[x],-k),add(c2,l[x],-1ll*k*d[x]);
 97 }
 98 int main(){ 
 99     fr(n),fr(m),fr(root);
100     for(it i=1;i<=n;++i) fr(w[i]);
101     for(it i=1;i<n;++i) fr(u),fr(v),Add();
102     DFS(root),dfs(root);
103     while(m--){
104         fr(opt),fr(u); 
105         if(opt==1){
106             fr(v),fr(k),lca();
107             ins(u),ins(v),del(lc);
108             if(fa[lc]) del(fa[lc]);
109         }
110         if(opt==2) printf("%lld
",q(c1,l[u],r[u])+w[u]);
111         if(opt==3) printf("%lld
",q(c2,l[u],r[u])+1ll*q(c1,l[u],r[u])*(1-d[u])+ww[u]);
112     }
113     return 0;
114 }
View Code

完美的树状数组+树上差分+树链剖分。。

原文地址:https://www.cnblogs.com/Kylin-xy/p/11625988.html