hdu5468(容斥原理)-2015 ACM/ICPC Asia Regional Shanghai Online
2015-09-28 11:08
405 查看
题意:给一颗以1为根的树,以每一个节点为子树,计算该子树的所有节点value与该节点value互质的节点个数。
假设第i个节点value为vi:
1、由莫比乌斯函数容斥求互质个数,显然需要预处理vi的无平方素数的因子(miu[vi] !=0的因子);
ans[i] = sigma( miu[d] * count[d] ),d为vi的无平方素数因子,count[d]为以第i个节点为根的子树中value为d的倍数的个数.
2、由上面的公式,容斥的时候需要知道count[d], 所以在遍历当前子树儿子节点之前统计所有的count1[d],在遍历完儿子节点之后统计所有的count2[d],
显然,count2[d]-count1[d]即为上式中的count[d].
ps:子树中vi自身也算,当且仅当vi=1的时候成立.
参考代码:
假设第i个节点value为vi:
1、由莫比乌斯函数容斥求互质个数,显然需要预处理vi的无平方素数的因子(miu[vi] !=0的因子);
ans[i] = sigma( miu[d] * count[d] ),d为vi的无平方素数因子,count[d]为以第i个节点为根的子树中value为d的倍数的个数.
2、由上面的公式,容斥的时候需要知道count[d], 所以在遍历当前子树儿子节点之前统计所有的count1[d],在遍历完儿子节点之后统计所有的count2[d],
显然,count2[d]-count1[d]即为上式中的count[d].
ps:子树中vi自身也算,当且仅当vi=1的时候成立.
参考代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<set> #include<map> #include<queue> #include<sstream> #include<string> #include<bitset> using namespace std; typedef long long LL; const LL LINF = (1LL <<63); const int INF = 1 << 31; const int NS = 100010; const int MS = 19; const int MOD = 1000000007; const int EDGE_MAX = NS; struct graphEdge { int pst; int next; }; struct ForwardStart { int top; int head[EDGE_MAX]; graphEdge edge[EDGE_MAX << 1]; void init(int len) { top = 0; memset(head, -1, sizeof(int) * len); } void addEdge(int u, int v) { edge[top].pst = v; edge[top].next = head[u]; head[u] = top++; } void printAll() { printf("top = %d\n", top); for(int i = 1; i < EDGE_MAX; i++) { if(-1 != head[i]) { printf("head[%2d]'son:%2d", i, edge[head[i]].pst); for(int j = edge[head[i]].next; j != -1; j = edge[j].next) { printf(",%2d", edge[j].pst); } puts(""); } } } }cTree; bitset<NS> isPrime; vector<int> fac[NS]; int miu[NS]; void prepare() { isPrime.set(); isPrime[1] = false; miu[1] = 1; for(int i = 2; i < NS; i++) { if(isPrime[i]) { for(int j = i; j < NS; j+=i) { isPrime[j] = false; int k = j / i; if(k % i) { miu[j] = -miu[k]; } else { miu[j] = 0; } fac[j].push_back(i); } } else { if(miu[i] != 0) { for(int j = i; j < NS; j+=i) { fac[j].push_back(i); } } } } } int n; int val[NS]; int ans[NS]; int sz[NS]; int dp[NS]; void dfs(int rt, int fa) { vector<int> temp; sz[rt] = 1; int value = val[rt]; int len = fac[value].size(); for(int i = 0; i < len; i++) { int d = fac[value][i]; int cnt = dp[d]; temp.push_back(cnt); dp[d] += 1; } for(int i = cTree.head[rt]; i != -1; i = cTree.edge[i].next) { int cson = cTree.edge[i].pst; if(cson == fa) continue; dfs(cson, rt); sz[rt] += sz[cson]; } ans[rt] = sz[rt]; for(int i = 0; i < len; i++) { int d = fac[value][i]; int cnt = dp[d] - temp[i]; if(cnt > 0) { ans[rt] += miu[d] * cnt; } } return ; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif prepare(); int nCase = 1; while(~scanf("%d", &n)) { cTree.init(n + n + 2); int u, v; for(int i = 1; i < n; i++) { scanf("%d %d", &u, &v); cTree.addEdge(u, v); cTree.addEdge(v, u); } for(int i = 1; i <= n; i++) { scanf("%d", &val[i]); if(val[i] < 0) { val[i] = - val[i]; } } memset(dp, 0, sizeof(dp)); dfs(1, -1); printf("Case #%d:", nCase++); for(int i = 1; i <= n; i++) { printf(" %d", ans[i]); } printf("\n"); } return 0; }
相关文章推荐
- ARC forbids explicit message send of 'retainCount'
- HDU 1022 Train Problem I (STL - 栈的使用)
- does not contain bitcode ShardSDK等三方库
- [个人推荐]理解poll_wait
- 【mongoDB中级篇②】索引与expain
- bsfl汇编指令 http://blog.csdn.net/chief1985/article/details/2441182
- SQUARE Probelm_codewars daily train9/27
- HT for Web 中Painter的介绍及用法
- HT for Web 中Painter的介绍及用法
- UVA 442 Matrix Chain Multiplication
- gtk+ 环境下,遇到assertion 'GTK_IS_NOTEBOOK (notebook)' failed,怎么破?
- 欧拉工程第74题:Digit factorial chains
- obtainKeywords
- 2015 ACM/ICPC Asia Regional Shanghai Online
- leetcode11 Container With Most Water
- Kafka错误1_kafka中 FailedToSendMessageException解决_修改host.name
- A child container failed during start
- Contains Duplicate III
- vs2010编译没有问题,然而运行出错Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.
- MainPage.xaml