12.6
状况百出的迎新杯。惶恐。
12.7
补个BC。
HDU 5593 ZYB‘s Tree
对树上每点求与其距离不超过k点数。k<=10.
一开始想的是用一个a[]存孩子中不超过k数,用另一个b[]存父亲传递过来的不超过k数。
但是这样转移不过来。因为父亲那边过来的不仅有父亲的父亲。还有父亲的其他孩子树。
所以想到换成用b[]存 父亲+所有孩子 不超过k数就可以转移了。
转移方程是 b[pos][i+1] = b[fa][i] - a[pos][i-1] + a[pos][i+1] 。
每个点的答案就是b[]求和。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 500000 + 10; 6 typedef long long LL; 7 int cnt, headlist[maxn]; 8 int a[maxn][11], b[maxn][11]; 9 int ans[maxn]; 10 LL N, K, A, B; 11 12 struct node 13 { 14 int to,pre; 15 } edge[maxn * 2]; 16 17 void add(int from,int to) 18 { 19 cnt++; 20 edge[cnt].pre = headlist[from]; 21 edge[cnt].to = to; 22 headlist[from] = cnt; 23 } 24 25 void dfs1(int pos, int fa) 26 { 27 a[pos][0] = 1; 28 for(int i = headlist[pos]; i; i = edge[i].pre) 29 { 30 int to = edge[i].to; 31 if(to == fa) continue; 32 dfs1(to, pos); 33 a[pos][1]++; 34 for(int j = 1; j < K; j++) a[pos][j+1] += a[to][j]; 35 } 36 return; 37 } 38 39 void dfs2(int pos, int fa) 40 { 41 if(fa != 0) 42 { 43 b[pos][1]++; 44 for(int i = 1; i < K; i++) b[pos][i+1] += b[fa][i] - a[pos][i-1]; 45 } 46 for(int i = 0; i <= K; i++) b[pos][i] += a[pos][i] ,ans[pos] += b[pos][i]; 47 for(int i = headlist[pos]; i; i = edge[i].pre) 48 { 49 int to = edge[i].to; 50 if(to == fa) continue; 51 dfs2(to, pos); 52 } 53 return; 54 } 55 56 int main(void) 57 { 58 int T; 59 scanf("%d", &T); 60 while(T--) 61 { 62 scanf("%I64d %I64d %I64d %I64d", &N, &K, &A, &B); 63 cnt = 0; 64 memset(headlist, 0, sizeof(headlist)); 65 memset(a, 0, sizeof(a)); 66 memset(b, 0, sizeof(b)); 67 memset(ans, 0, sizeof(ans)); 68 for(LL i = 2; i <= N; i++) 69 { 70 LL b = (A * i + B) % (i - 1) + 1; 71 add(i, b); 72 add(b, i); 73 } 74 dfs1(1,0); 75 dfs2(1,0); 76 int ret = 0; 77 for(int i = 1; i <= N; i++) ret ^= ans[i]; 78 printf("%d\n", ret); 79 } 80 return 0; 81 }
原文:http://www.cnblogs.com/Aguin/p/5027267.html