Description
Input
Output
Sample Input
input | output |
---|---|
4 1 1 1 1 1 2 1 3 2 4 9 2 1 2 2 2 3 2 4 1 1 2 1 2 2 2 3 2 4 |
1 1 1 1 1 2 2 1 |
2 1 1 1 2 14 2 2 2 1 1 1 2 2 1 2 2 1 1 1 2 2 1 2 2 1 1 1 2 2 1 2 2 1 |
1 1 2 3 5 8 13 21 |
题解:把结点分层两类, 孩子结点大于 sqrt(n) 个的 , 孩子结点小于 sqrt(n) 。对前面的离线更新, 后面的在线更新 。
#include <iostream> #include <vector> using namespace std; typedef long long LL; const int N = 100050; const int M = 111; const int MOD = 1e9 + 7; LL ans[N],out[N]; vector<int> cop[N],top[N]; void Add(LL &a, const LL b) { a += b; if (a >= MOD) { a -= MOD; } } int main() { ios::sync_with_stdio(0); int n; while(cin>>n) { for(int i=1;i<=n;i++) {cin>>ans[i];out[i]=0;} for(int i=0;i<n-1;i++) { int a,b;cin>>a>>b; cop[a].push_back(b); cop[b].push_back(a); } for(int i=1;i<=n;i++) for(int j=0;j<cop[i].size();j++) if(cop[cop[i][j]].size()>M) top[i].push_back(cop[i][j]); int m;cin>>m; while(m--) { int a,b;cin>>a>>b; if(a==1) { if(cop[b].size()>M) { for(int i=0;i<top[b].size();i++) Add(ans[top[b][i]],ans[b]); Add(out[b],ans[b]); } else { LL x=ans[b]; for(int i=0;i<cop[b].size();i++) Add(x,out[cop[b][i]]); for(int i=0;i<top[b].size();i++) Add(ans[top[b][i]],x); Add(out[b],x); } } else { if(cop[b].size()>M) cout<<ans[b]<<endl; else { LL x=ans[b]; for(int i=0;i<cop[b].size();i++) Add(x,out[cop[b][i]]); cout<<x<<endl; } } } } return 0; }
原文:http://www.cnblogs.com/BugClearlove/p/4413990.html