标签:
一道比较好的树分治的题目.大力推荐~
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 479 Accepted Submission(s): 163
1 #include<cstdlib> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #include<cctype> 7 using namespace std; 8 const int maxn = (int)3e5, inf = 0x3f3f3f3f; 9 struct E{ 10 int t,w,last; 11 }e[maxn * 4]; 12 struct EE{ 13 int rt,srt,dis,last; 14 }ee[maxn * 6]; 15 int ll[maxn * 6],edge; 16 int last[maxn * 4],edg; 17 int n,q; 18 inline int getint(){ 19 int ret = 0; char ch = getchar(); 20 while(!isdigit(ch)) ch = getchar(); 21 while(isdigit(ch)) ret = ret * 10 + ch - ‘0‘, ch = getchar(); 22 return ret; 23 } 24 inline void add2(int x,int rt,int srt,int dis){ 25 ee[++edge] = (EE){rt,srt,dis,ll[x]}; ll[x] = edge; 26 } 27 inline void add(int x,int y,int w){ 28 e[++edg] = (E){y,w,last[x]}; last[x] = edg; 29 e[++edg] = (E){x,w,last[y]}; last[y] = edg; 30 } 31 int w[maxn]; 32 int vis[maxn]; 33 int sz[maxn],tmax,node,root; 34 void getroot(int x,int fa){ 35 sz[x] = 0; 36 int Max = 0; 37 for(int i = last[x]; i; i = e[i].last) 38 if(!vis[e[i].t] && e[i].t != fa){ 39 getroot(e[i].t, x); 40 sz[x] += sz[e[i].t] + 1; 41 Max = max(Max, sz[e[i].t] + 1); 42 } 43 Max = max(Max, node - sz[x] - 1); 44 if(tmax > Max) tmax = Max, root = x; 45 } 46 struct BIT{ 47 vector<int>v; 48 void init(int sz){ 49 v.clear(); v.resize(sz + 2); 50 } 51 inline int lowbit(int x){ 52 return x & (-x); 53 } 54 void add(int pos,int val){ 55 for(++pos; pos < (int)v.size(); pos += lowbit(pos)) v[pos] += val; 56 } 57 int qer(int pos){ 58 pos = min(pos + 1, (int)v.size() - 1); 59 int ret = 0; 60 for(; pos > 0; pos -= lowbit(pos)) ret += v[pos]; 61 return ret; 62 } 63 }T[maxn * 3]; 64 int cur; 65 int rt,srt,dist; 66 void getdata(int pt,int k, int x, int fa, int dis){ 67 if(k) add2(x,k,pt,dis); 68 T[pt].add(dis, w[x]); 69 for(int i = last[x]; i; i = e[i].last) 70 if(!vis[e[i].t] && e[i].t != fa) 71 getdata(pt, k, e[i].t, x, dis + e[i].w); 72 } 73 void dfs(int x,int size){ 74 int p; 75 T[p = ++cur].init(size); 76 getdata(p, 0, x, 0, 0); 77 add2(x, p, 0, 0); 78 vis[x] = 1; 79 for(int i = last[x]; i; i = e[i].last) 80 if(!vis[e[i].t]){ 81 tmax = inf, node = sz[e[i].t]; 82 getroot(e[i].t, root = 0); 83 T[++cur].init(sz[e[i].t] + 1); 84 getdata(cur, p, e[i].t, 0, e[i].w); 85 dfs(root,sz[e[i].t]); 86 } 87 } 88 void work(){ 89 tmax = inf, node = n; 90 getroot(1,root = 0); 91 dfs(root,n); 92 } 93 void query(){ 94 int x = getint(), d = getint(); 95 int ret = 0; 96 for(int i = ll[x]; i; i = ee[i].last){ 97 int rt = ee[i].rt, srt = ee[i].srt, dis = ee[i].dis; 98 ret += T[rt].qer(d - dis); 99 if(srt) ret -= T[srt].qer(d - dis); 100 } 101 printf("%d\n",ret); 102 } 103 void maintain(){ 104 int x = getint(), ww = getint(); 105 for(int i = ll[x]; i; i = ee[i].last){ 106 int rt = ee[i].rt,srt = ee[i].srt,dis = ee[i].dis; 107 T[rt].add(dis, ww - w[x]); 108 if(srt) T[srt].add(dis, ww - w[x]); 109 } 110 w[x] = ww; 111 } 112 void solve(){ 113 char op; 114 while(q--){ 115 scanf("%c\n",&op); 116 if(op == ‘?‘) query(); 117 else maintain(); 118 } 119 } 120 void init(){ 121 memset(vis,0,sizeof(vis)); 122 memset(last,0,sizeof(last)); 123 memset(ll,0,sizeof(ll)); 124 cur = edge = edg = 0; 125 } 126 int main() 127 { 128 freopen("subtree.in","r",stdin); 129 freopen("subtree.out","w",stdout); 130 while(scanf("%d %d",&n,&q) != EOF){ 131 for(int i = 1; i <= n; ++i) w[i] = getint(); 132 for(int i = 1; i < n; ++i){ 133 int u = getint(), v = getint(); 134 add(u,v,1); 135 } 136 work(); 137 solve(); 138 init(); 139 } 140 return 0; 141 }
标签:
原文地址:http://www.cnblogs.com/Mr-ren/p/4215523.html