bzoj2783 [JLOI2012]樹
阿新 • • 發佈:2017-09-27
iterator != script while 多行 開始 bsp long scrip
1 2 3
1 2
1 3
Description
數列 提交文件:sequence.pas/c/cpp 輸入文件:sequence.in 輸出文件:sequence.out 問題描述: 把一個正整數分成一列連續的正整數之和。這個數列必須包含至少兩個正整數。你需要求出這個數列的最小長度。如果這個數列不存在則輸出-1。 輸入格式: 每行包含一個正整數n。 每個文件包含多行,讀入直到文件結束。 輸出格式: 對於每個n,輸出一行,為這個數列的最小長度。第一行是兩個整數N和S,其中N是樹的節點數。
第二行是N個正整數,第i個整數表示節點i的正整數。
接下來的N-1行每行是2個整數x和y,表示y是x的兒子。
輸出格式:
輸出路徑節點總和為S的路徑數量。
輸入樣例: |
輸出樣例: |
3 3 1 2 3 1 2 1 3 |
2 |
數據範圍:
對於30%數據,N≤100;
對於60%數據,N≤1000;
對於100%數據,N≤100000,所有權值以及S都不超過1000。
數據範圍: 對於所有數據,n≤263。這個是JLOI2012的T1,發出來僅為了試題完整
=============================================================================================
在這個問題中,給定一個值S和一棵樹。在樹的每個節點有一個正整數,問有多少條路徑的節點總和達到S。路徑中節點的深度必須是升序的。假設節點1是根節點,根的深度是0,它的兒子節點的深度為1。路徑不必一定從根節點開始。
Input
第一行是兩個整數N和S,其中N是樹的節點數。
第二行是N個正整數,第i個整數表示節點i的正整數。
接下來的N-1行每行是2個整數x和y,表示y是x的兒子。
Output
輸出路徑節點總和為S的路徑數量。
Sample Input
3 31 2 3
1 2
1 3
Sample Output
2HINT
對於100%數據,N≤100000,所有權值以及S都不超過1000。
正解:$set$啟發式合並。
題面鬼得不行。。
比較簡單的一個題,直接在樹上用啟發式合並即可,我偷懶所以寫了個$multiset$。。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define N (200010) 6 7 using namespace std; 8 9 struct edge{ int nt,to; }g[N<<1]; 10 11 int head[N],val[N],son[N],sz[N],rt[N],tim[N],num,n,S; 12 ll ans; 13 14 multiset<int> st[N]; 15 16 multiset<int>:: iterator it; 17 18 il int gi(){ 19 RG int x=0,q=1; RG char ch=getchar(); 20 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 21 if (ch==‘-‘) q=-1,ch=getchar(); 22 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 23 return q*x; 24 } 25 26 il void insert(RG int from,RG int to){ 27 g[++num]=(edge){head[from],to},head[from]=num; return; 28 } 29 30 il void dfs(RG int x,RG int p){ 31 sz[x]=1; RG int v,tr; 32 for (RG int i=head[x];i;i=g[i].nt){ 33 v=g[i].to; if (v==p) continue; 34 dfs(v,x),sz[x]+=sz[v]; 35 if (sz[son[x]]<=sz[v]) son[x]=v; 36 } 37 if (val[x]==S) ++ans; 38 if (!son[x]){ rt[x]=x,st[x].insert(val[x]); return; } 39 rt[x]=rt[son[x]],tim[rt[x]]+=val[x],tr=rt[x]; 40 ans+=st[tr].count(S-tim[tr]); 41 for (RG int i=head[x],Rt,d;i;i=g[i].nt){ 42 v=g[i].to; if (v==p || v==son[x]) continue; Rt=rt[v]; 43 for (it=st[Rt].begin();it!=st[Rt].end();++it){ 44 d=(*it)+tim[Rt]+val[x]; if (d==S) ++ans; 45 if (d<=S) st[tr].insert(d-tim[tr]); 46 } 47 st[Rt].clear(); 48 } 49 st[tr].insert(val[x]-tim[tr]); return; 50 } 51 52 int main(){ 53 #ifndef ONLINE_JUDGE 54 freopen("tree.in","r",stdin); 55 freopen("tree.out","w",stdout); 56 #endif 57 n=gi(),S=gi(); 58 for (RG int i=1;i<=n;++i) val[i]=gi(); 59 for (RG int i=1,x,y;i<n;++i) 60 x=gi(),y=gi(),insert(x,y),insert(y,x); 61 dfs(1,0),cout<<ans; return 0; 62 }
bzoj2783 [JLOI2012]樹