HDU 5468 Puzzled Elena(DFS序+容斥原理)
題目連結:傳送門
題意:
給定一棵樹,求這個節點的所有子樹中包括他本身與它互質的節點的個數。
分析:轉自傳送門
因為每個數的大小<=100000 這個範圍內 2*3*5*7*11*13 *17> 100000 最多隻有 6 個素因子。
當我們知道這個怎麼處理以後,我們可以利用dfs序,解決這個問題
我們求當前這個節點的答案時,用容斥搞就是:以這個節點為根的樹的大小 - 有1個素因子和他相同的節點個數 + 有2個素因子和他相同的個數 - 有3個素因子和他相同的個數 ....
那麼問題來了,我們如何求出有多少個 有1個素因子和他相同的個數,有2個素因子和他相同的個數 ,,,,,
我們維護一個數fac[]陣列,fac[i] 代表包含因子i的節點個數。
那麼在這顆樹中,進入這顆樹之前求一下(有1個素因子和他相同的節點個數,有2個素因子和他相同的節點個數.....),離開這顆樹的時候再求一下(有1個素因子和他相同的節點個數,有2個素因子和他相同的節點個數.....),他們的差便是我們需要的(子樹中的和他有關係的資訊)。
到這裡,問題就解決了,容斥版的做法 時間複雜度 O(n*2^6 + nlogn) :
程式碼如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int fac[maxn];
int w[maxn];
int ans[maxn];
struct Graph{
vector<int >vc[maxn];
void init(){
for(int i=0;i<maxn;i++)
vc[i].clear();
}
void add(int u,int v){
vc[u].push_back(v);
}
}G1,G2;
void prepare(){
G1.init();
for(int i=2;i<maxn;i++){
if(G1.vc[i].size())
continue;
for(int j=i;j<maxn;j+=i)
G1.add(j,i);
}
}
int calc(int u,int x){
int ans = 0,n=G1.vc[u].size();
for(int i=1;i<(1<<n);i++){
int tot=1,cnt=0;
for(int j=0;j<n;j++){
if((1<<j)&i){
cnt++;
tot=tot*G1.vc[u][j];
}
}
if(cnt&1)
ans = ans+fac[tot];
else
ans = ans-fac[tot];
fac[tot]+=x;
}
return ans;
}
int dfs(int u,int pre){
int cnt = 0;
int L = calc(w[u],0);
for(int i=0;i<G2.vc[u].size();i++){
int v = G2.vc[u][i];
if(v==pre) continue;
cnt+=dfs(v,u);
}
int R = calc(w[u],1);
ans[u]=cnt-(R-L);
if(w[u]==1) ans[u]++;
return cnt+1;
}
int main()
{
prepare();
int n,cas=1;
while(~scanf("%d",&n)){
G2.init();
memset(fac,0,sizeof(fac));
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
G2.add(u,v);
G2.add(v,u);
}
for(int i=1;i<=n;i++)
scanf("%d",w+i);
dfs(1,0);
printf("Case #%d: ",cas++);
for(int i=1;i<=n;i++){
printf("%d%c",ans[i],i==n? '\n':' ');
}
}
return 0;
}
相關文章
- HDU 4135 Co-prime(容斥原理+分解質因數)
- 容斥原理
- 【模板】容斥原理
- HDU 4135——Co-prime(容斥原理&&二進位制列舉)
- 容斥原理學習筆記筆記
- 容斥原理——數學知識
- 容斥
- P1447 [NOI2010] 容斥原理
- dfs序
- 反射容斥反射
- 樹的DFS序
- HDU1427速算24點(dfs)
- HDU 1427-速算24點(DFS)
- HDU - 2553 N皇后問題(DFS)
- Min-Max 容斥
- lg容斥與反演
- cf449D. Jzzhu and Numbers(容斥原理 高維字首和)
- hdu 6446 Tree and Permutation(dfs+思維)
- DFS序例題+感受
- 容斥定理 AtCoder——FizzBuzz Sum Hard
- DFS演算法原理演算法
- P4178 Tree——點分治 容斥
- Codefroces 1328E Tree Querie(dfs序)
- Min-Max 容斥學習筆記筆記
- CodeForces571A. Lengthening Sticks(組合數學-容斥)
- bzoj2809: [Apio2012]dispatching(DFS序+主席樹)API
- cf900D. Unusual Sequences(容斥 莫比烏斯反演)
- 機率期望進階 + Min-Max容斥 練習題
- 「數學」助力每一個不知死活的容斥夢
- bzoj1803: Spoj1487 Query on a tree III(DFS序+主席樹)
- CF 773 (Div. 1) D. Two Arrays 雙指標 容斥指標
- bzoj3439: Kpm的MC密碼(主席樹+DFS序+字典樹)密碼
- HashMap擴容原理HashMap
- DFS
- 從 dfs 序求 lca 到虛樹到樹分塊 學習筆記筆記
- hdu 2111 Saving HDU (DP)
- 【演算法】二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的遞迴和迭代實現記錄(Java版)演算法二叉樹遞迴Java
- DFS樹
- dfs技巧