51nod1462 树据结构

$n \leq 100000$的树支持$m \leq 100000$个操作:每个点有两个权值$a$和$b$,一,链加;二,链上$b_i+=a_i*d$,问最后所有的$b_i$。

这个题我在看到之前有想过链上的情况,当时以为标记是O(1)下传的就没细想。现在看来需要一些特殊技巧。首先链剖加线段树。

方法一:把$a$的区间加标记永久化,然后记标记:$b$的区间共同增量;$b$的区间增加次数。下传时,$a$不下传,次数直接加给儿子后清零,增量$zeng_{son}+=zeng_{fa}+abiaoji_{son}*cishu_{fa}$。最后所有标记一起推下去。

方法二:可用一个矩阵进行一次操作:转自此

  1 //#include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 //#include<time.h>
  5 //#include<complex>
  6 //#include<set>
  7 #include<queue>
  8 //#include<vector>
  9 #include<algorithm>
 10 #include<stdlib.h>
 11 using namespace std;
 12 
 13 #define LL long long
 14 int qread()
 15 {
 16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
 17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
 18 }
 19 
 20 //Pay attention to '-' , LL and double of qread!!!!
 21 
 22 int n,m;
 23 #define maxn 200011
 24 
 25 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2;
 26 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
 27 
 28 int fa[maxn],id[maxn],top[maxn],dep[maxn],size[maxn],hea[maxn],Time=0,list[maxn];
 29 void dfs1(int x)
 30 {
 31     size[x]=1;
 32     for (int i=first[x];i;i=edge[i].next)
 33     {
 34         Edge &e=edge[i];
 35         dep[e.to]=dep[x]+1; fa[e.to]=x;
 36         dfs1(e.to);
 37         size[x]+=size[e.to]; if (size[e.to]>size[hea[x]]) hea[x]=e.to;
 38     }
 39 }
 40 void dfs2(int x,int from)
 41 {
 42     top[x]=from; id[x]=++Time; list[Time]=x;
 43     if (hea[x]) dfs2(hea[x],from);
 44     for (int i=first[x];i;i=edge[i].next)
 45     {
 46         Edge &e=edge[i]; if (e.to==hea[x]) continue;
 47         dfs2(e.to,e.to);
 48     }
 49 }
 50 
 51 LL ans[maxn];
 52 struct SMT
 53 {
 54     struct Node
 55     {
 56         int ls,rs;
 57         LL sv,st,nt;
 58     }a[maxn<<1];
 59     int size,n;
 60     void build(int &x,int L,int R)
 61     {
 62         x=++size; if (L==R) return;
 63         int mid=(L+R)>>1;
 64         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R);
 65     }
 66     void clear(int N) {n=N; size=0; int x; build(x,1,n);}
 67     void addsingle(int x,LL fst,LL fnt)
 68     {
 69         a[x].st+=fst+a[x].sv*fnt;
 70         a[x].nt+=fnt;
 71     }
 72     void down(int x)
 73     {addsingle(a[x].ls,a[x].st,a[x].nt); addsingle(a[x].rs,a[x].st,a[x].nt); a[x].st=a[x].nt=0;}
 74     int ql,qr,d; LL vv;
 75     void OP1(int x,int L,int R)
 76     {
 77         if (ql<=L && R<=qr) {a[x].sv+=d; return;}
 78         down(x);
 79         int mid=(L+R)>>1;
 80         if (ql<=mid) OP1(a[x].ls,L,mid);
 81         if (qr>mid) OP1(a[x].rs,mid+1,R);
 82     }
 83     void op1(int L,int R,int d) {ql=L; qr=R; this->d=d; OP1(1,1,n);}
 84     void OP2(int x,int L,int R)
 85     {
 86         if (ql<=L && R<=qr) {a[x].st+=(vv+a[x].sv)*d; a[x].nt+=d; return;}
 87         down(x); vv+=a[x].sv;
 88         int mid=(L+R)>>1;
 89         if (ql<=mid) OP2(a[x].ls,L,mid);
 90         if (qr>mid) OP2(a[x].rs,mid+1,R);
 91         vv-=a[x].sv;
 92     }
 93     void op2(int L,int R,int d) {ql=L; qr=R; this->d=d; vv=0; OP2(1,1,n);}
 94     
 95     void dfs(int x,int L,int R)
 96     {
 97         if (L==R)
 98         {
 99             int u=list[L];
100             ans[u]=a[x].st;
101             return;
102         }
103         down(x);
104         int mid=(L+R)>>1;
105         dfs(a[x].ls,L,mid); dfs(a[x].rs,mid+1,R);
106     }
107     void dfs() {dfs(1,1,n);}
108 }t;
109 
110 void ope(int x,int y,int d,int type)
111 {
112     while (top[x]!=top[y])
113     {
114         if (dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
115         if (type==1) t.op1(id[top[x]],id[x],d);
116         else t.op2(id[top[x]],id[x],d);
117         x=fa[top[x]];
118     }
119     if (dep[x]>dep[y]) x^=y^=x^=y;
120     if (type==1) t.op1(id[x],id[y],d);
121     else t.op2(id[x],id[y],d);
122 }
123 
124 int main()
125 {
126     n=qread();
127     for (int i=2,x;i<=n;i++) {x=qread(); in(x,i);}
128     dfs1(1); dfs2(1,1);
129     
130     t.clear(n);
131     m=qread();
132     int op,x,d;
133     while (m--)
134     {
135         op=qread(); x=qread(); d=qread();
136         ope(1,x,d,op);
137     }
138     t.dfs();
139     for (int i=1;i<=n;i++) printf("%lld\n",ans[i]);
140     return 0;
141 }
View Code

 

posted @ 2018-06-11 20:53  Blue233333  阅读(179)  评论(0编辑  收藏  举报