COJ 0990 WZJ 의 데이터 구조 (마이너스 10)
18420 단어 데이터 구조
WZJ 의 데이터 구조 (마이너스 10)
난이도 레벨: D;운행 시간 제한: 5000 ms;실행 공간 제한: 51200 KB;코드 길이 제한: 2000000 B
시험 문제 설명
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 인 조작 에 대해 한 줄 의 정 수 를 출력 하여 이번 질문 의 답 을 나타 낸다.
예제 입력
6112224 5 7 1 2 34Q 2F 1 3Q 2Q 5
출력 예시
91520
기타 설명
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;}
수색 하 다.
복제 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.