COJ 0990 WZJ的数据结构(负十)

WZJ的数据结构(负十)
难度级别:D; 运行时间限制:5000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

给你一个N个节点的有根树,从1到N编号,根节点为1并给出每个点的权值与父亲节点。请你设计一个数据结构,进行以下两种操作:

F x v : 将节点x的子树的每个节点权值+v

Q x : 询问节点x到其根的路径上的节点权值之和

输入
第一行一个正整数N。
接下来N-1行每行一个正整数,分别表示节点2-n的父亲节点编号。
接下来一行N个正整数,表示每个节点的初始权值。
再接下来一行一个正整数M,表示操作的总数。
操作分为以下两种类型。
(1)"Q x"表示询问节点x到其根的路径上的节点权值之和.
(2)"F x v"表示将节点x的子树的每个节点权值+v.
输出
对于每一个操作类型为Q的操作,输出一行一个整数,表示此次询问的答案。
输入示例
6
1
1
2
2
2
4 5 7 1 2 3
4
Q 2
F 1 3
Q 2
Q 5
输出示例
9
15
20
其他说明
1<=N,M<=100000
1<=pi,x<=N
1<=wi<=10^6
1<=v<=1000

今天跟健学了DFS序。。。原来就这么回事,注意好符号、出入。

还有,以后的AddEdge注意好顺序!!!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(' ')
 8 #define ENT putchar('
')
 9 using namespace std;
10 typedef long long LL;
11 const int maxn=200000+10,maxn3=600000+10,inf=-1u>>1;
12 LL addv[maxn3],sumv[maxn3],siz[maxn3],_sum;int n,Q,sig[maxn],A[maxn],si[maxn],so[maxn],cz=0,ql,qr,cv;
13 struct Tedge{int x,y,next;}adj[maxn];int ms=0,fch[maxn];
14 void AddEdge(int u,int v){adj[++ms]=(Tedge){u,v,fch[u]};fch[u]=ms;return;}
15 void dfs(int u){
16     si[u]=++cz;sig[cz]=1;
17     for(int i=fch[u];i;i=adj[i].next) dfs(adj[i].y);
18     so[u]=++cz;sig[cz]=-1;
19     return;
20 }
21 void maintain(int o,int L,int R){
22     int lc=o<<1,rc=lc|1;
23     if(L<R) sumv[o]=sumv[lc]+sumv[rc]; else sumv[o]=0;
24     sumv[o]+=addv[o]*siz[o];return;
25 }
26 void build(int o,int L,int R){
27     if(L==R) addv[o]=A[L],siz[o]=sig[L];
28     else{
29         int M=L+R>>1,lc=o<<1,rc=lc|1;
30         build(lc,L,M);build(rc,M+1,R);
31         siz[o]=siz[lc]+siz[rc];
32     } maintain(o,L,R);return;
33 }
34 void update(int o,int L,int R){
35     if(ql<=L&&R<=qr) addv[o]+=cv;
36     else{
37         int M=L+R>>1,lc=o<<1,rc=lc|1;
38         if(ql<=M) update(lc,L,M);
39         if(qr>M) update(rc,M+1,R);
40     } maintain(o,L,R);return;
41 }
42 void query(int o,int L,int R,int add){
43     if(ql<=L&&R<=qr) _sum+=add*siz[o]+sumv[o];
44     else{
45         int M=L+R>>1,lc=o<<1,rc=lc|1;
46         if(ql<=M) query(lc,L,M,add+addv[o]);
47         if(qr>M) query(rc,M+1,R,add+addv[o]);
48     } return;
49 }
50 inline int read(){
51     int x=0,sig=1;char ch=getchar();
52     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
53     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
54     return x*=sig;
55 }
56 inline void write(int x){
57     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
58     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
59     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
60 }
61 inline void write(LL x){
62     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
63     int len=0;LL buf[15];while(x)buf[len++]=x%10,x/=10;
64     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
65 }
66 inline char readc(){
67     char tp;for(tp=getchar();!isalpha(tp);tp=getchar());return tp;
68 }
69 void init(){
70     n=read();
71     for(int i=2;i<=n;i++) AddEdge(read(),i); dfs(1);
72     for(int i=1;i<=n;i++) A[si[i]]=A[so[i]]=read(); build(1,1,n<<1);
73     return;
74 }
75 void work(){
76     Q=read();
77     while(Q--){
78         if(readc()=='Q'){
79             _sum=0;
80             ql=1;qr=si[read()];query(1,1,n<<1,0);
81             write(_sum);ENT;
82         }
83         else{
84             ql=read();
85             qr=so[ql];ql=si[ql];cv=read();
86             update(1,1,n<<1);
87         }
88     }
89     return;
90 }
91 void print(){
92     return;
93 }
94 int main(){init();work();print();return 0;}
原文地址:https://www.cnblogs.com/chxer/p/4523561.html