HDU-3966 Aragorn's Story(樹鏈剖分+線段樹)
阿新 • • 發佈:2017-08-12
real letter 們的 等等 then 需要 family sea inpu
Input
Multiple test cases, process to the end of
input.
For each case, The first line contains three integers N, M, P which means there will be N(1 ≤ N ≤ 50000) camps, M(M = N-1) edges and P(1 ≤ P ≤ 100000) operations. The number of camps starts from 1.
The next line contains N integers A1, A2, ...AN(0 ≤ Ai ≤ 1000), means at first in camp-i has Ai enemies.
The next M lines contains two integers u and v for each, denotes that there is an edge connects camp-u and camp-v.
The next P lines will start with a capital letter ‘I‘, ‘D‘ or ‘Q‘ for each line.
‘I‘, followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, increase K soldiers to these camps.
‘D‘, followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, decrease K soldiers to these camps.
‘Q‘, followed by one integer C, which is a query and means Aragorn wants to know the number of enemies in camp C at that time.
Output
For each query, you need to output the actually number
of enemies in the specified camp.
Recommend
We have carefully selected several similar problems for
you: 3964 3965 3962 3963 3967
HDU是真雞巴垃圾的一個OJ 老子的程序明明沒有什麽問題 結果判我RE
今天學了樹鏈剖分 簡單來說就是把樹上的節點標個號 然後拆成一條條鏈來操作,這一條條鏈的一個重要的性質是他們的編號都是連在一起的 這些操作比如區間修改查詢等需要依托線段樹,splay等等數據結構來實現
好吧這是目前為止寫的最長的程序。。。。。
Aragorn‘s Story
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12479 Accepted Submission(s):
3331
For each case, The first line contains three integers N, M, P which means there will be N(1 ≤ N ≤ 50000) camps, M(M = N-1) edges and P(1 ≤ P ≤ 100000) operations. The number of camps starts from 1.
The next line contains N integers A1, A2, ...AN(0 ≤ Ai ≤ 1000), means at first in camp-i has Ai enemies.
The next M lines contains two integers u and v for each, denotes that there is an edge connects camp-u and camp-v.
The next P lines will start with a capital letter ‘I‘, ‘D‘ or ‘Q‘ for each line.
‘I‘, followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, increase K soldiers to these camps.
‘D‘, followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, decrease K soldiers to these camps.
‘Q‘, followed by one integer C, which is a query and means Aragorn wants to know the number of enemies in camp C at that time.
Sample Input 3 2 5 1 2 3 2 1 2 3 I 1 3 5 Q 2 D 1 2 2 Q 1 Q 3
Sample Output 7 4 8 Hint 1.The number of enemies may be negative. 2.Huge input, be careful.
Source 2011 Multi-University Training Contest 13 - Host by HIT
1 #pragma comment(linker, "/STACK:1024000000,1024000000") //據說這玩意可以手動擴棧 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <iostream> 10 #include "algorithm" 11 #define mem(a,b) memset(a,b,sizeof(a)) 12 using namespace std; 13 typedef long long LL; 14 const int MAX=50005; 15 int n,m,T; 16 int tot,ttt; 17 int head[MAX],adj[MAX<<2],nex[MAX<<2]; 18 int a[MAX],deep[MAX],fa[MAX]; 19 int siz[MAX],son[MAX],top[MAX],tid[MAX],rak[MAX]; 20 void addedge(int u,int v){ 21 tot++; 22 adj[tot]=v; 23 nex[tot]=head[u]; 24 head[u]=tot; 25 } 26 void init(){ 27 int i,j; 28 mem(head,0),mem(son,0); 29 tot=ttt=0; 30 } 31 void dfs1(int x,int ff,int de){ //標父親,後代個數(包括自己),深度,重兒子 32 int i,j; 33 deep[x]=de; 34 siz[x]=1;fa[x]=ff; 35 for (i=head[x];i;i=nex[i]){ 36 int v=adj[i]; 37 if (v==ff) continue; 38 dfs1(v,x,de+1); 39 siz[x]+=siz[v]; 40 if (!son[x] || siz[v]>siz[son[x]]){ 41 son[x]=v; 42 } 43 } 44 } 45 void dfs2(int x,int tp){//編號,拆樹 46 int i,j; 47 top[x]=tp; 48 tid[x]=++ttt; 49 rak[tid[ttt]]=x; 50 if (!son[x]) return; 51 dfs2(son[x],tp); 52 for (i=head[x];i;i=nex[i]){ 53 if (adj[i]!=son[x] && adj[i]!=fa[x]){ 54 dfs2(adj[i],adj[i]); 55 } 56 } 57 } 58 //線段樹 59 #define lson rt<<1,l,m 60 #define rson rt<<1|1,m+1,r 61 int sum[MAX<<2],la[MAX<<2]; 62 63 void PushUp(int rt){ 64 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 65 } 66 void PushDown(int rt,int l,int r){ 67 if (la[rt]){ 68 int m=(l+r)>>1; 69 la[rt<<1]+=la[rt];la[rt<<1|1]+=la[rt]; 70 sum[rt<<1]+=(m-l+1)*la[rt]; 71 sum[rt<<1|1]+=(r-m)*la[rt]; 72 la[rt]=0; 73 } 74 } 75 void build(int rt,int l,int r){ 76 la[rt]=0; 77 if(l==r){ 78 sum[rt]=a[rak[l]]; 79 return; 80 } 81 int m=(l+r)>>1; 82 build(lson); 83 build(rson); 84 PushUp(rt); 85 } 86 void update(int rt,int l,int r,int x,int y,int z){ 87 if (x<=l && r<=y){ 88 sum[rt]+=z*(r-l+1); 89 la[rt]+=z; 90 return; 91 } 92 int m=(l+r)>>1; 93 PushDown(rt,l,r); 94 if (x<=m) update(lson,x,y,z); 95 if (y>m) update(rson,x,y,z); 96 PushUp(rt); 97 } 98 int search(int rt,int l,int r,int x){ 99 if (l==r){ 100 return sum[rt]; 101 } 102 int res=0; 103 int m=(l+r)>>1; 104 PushDown(rt,l,r); 105 if (x<=m) res+=search(lson,x); 106 if (x>m) res+=search(rson,x); 107 PushUp(rt); 108 return res; 109 } 110 void calc(int x,int y,int z){ 111 int i,j; 112 while (top[x]!=top[y]){ 113 if (deep[x]<deep[y]) swap(x,y); 114 update(1,1,n,tid[top[x]],tid[x],z); 115 x=fa[top[x]]; 116 } 117 if (deep[x]>deep[y]) swap(x,y); 118 update(1,1,n,tid[x],tid[y],z); 119 } 120 int main(){ 121 freopen ("story.in","r",stdin); 122 freopen ("story.out","w",stdout); 123 int i,j; 124 int u,v,x,y,z; 125 char c; 126 while (~scanf("%d%d%d",&n,&m,&T)){ 127 init(); 128 for (i=1;i<=n;i++){ 129 scanf("%d",a+i); 130 } 131 for (i=1;i<=m;i++){ 132 scanf("%d%d\n",&u,&v); 133 addedge(u,v); 134 addedge(v,u); 135 } 136 dfs1(1,0,1); 137 dfs2(1,1); 138 build(1,1,n); 139 while (T--){ 140 c=getchar();//cout<<c<<endl; 141 if (c==‘Q‘){ 142 scanf("%d\n",&x); 143 printf("%d\n",search(1,1,n,tid[x])); 144 } 145 else{ 146 scanf("%d%d%d\n",&x,&y,&z); 147 if (c==‘D‘) z=-z; 148 calc(x,y,z); 149 } 150 } 151 } 152 return 0; 153 }
HDU-3966 Aragorn's Story(樹鏈剖分+線段樹)