計蒜客 青雲的機房組網方案(莫比烏斯函式+樹上dsu)
題意
給定一棵
個節點的樹,每個節點上有一個點權,邊權為均
,求所有點權互質的點對路徑總和。
思路
對於一個數
,能與它產生貢獻的數和
沒有公共質因子,那我們可以通過篩出莫比烏斯係數,就可以用容斥的方法求出與
互質的部分了,如下圖:
為 的三個質因子,與 互質的部分就是上面的
莫比烏斯係數篩法如下:
FOR(i,1,N)mo[i]=1,mark[i]=0;
FOR(i,2,N)if(!mark[i])
{
for(int j=i;j<=N;j+=i)
{
mark[j]=1;
if(j/i%i==0)mo[j]=0;
else mo[j]=-mo[j];
}
}
其中
若一個數有一個因子是某個質數平方,那這個集合是某一個質數代表集合的子集,不會有貢獻計算。即一個數表示成若干個質數的幾次冪相乘時,這個冪次只能是
。除此外,有偶數個質因子的莫比烏斯函式值是
,奇數個為
。
那我們不妨列舉
,計算每一個父節點中符合條件的子節點對的貢獻,單獨對某個因子而言,兩個同時是這個因子倍數的數將產生貢獻,乘上莫比烏斯係數再累和就是所有的貢獻。
貢獻的演算法只用化開式子即可,對於因子
,某一個節點
,給定所有節點的
時,對答案的貢獻就是
,其中
屬於
不同子節點的子樹。
然後我們有
設
為目前全域性陣列中
倍數的節點深度總和,
為個數總和。
維護好
和
陣列,每新增一棵子樹就計算一次貢獻即可。
把它改成
複雜度就變成
了。
#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
typedef long long LL;
using namespace std;
const int N=1e5+3;
template<const int maxn,const int maxm>struct Linked_list
{
int head[maxn],to[maxm],nxt[maxm],tot;
Linked_list(){clear();}
void clear(){memset(head,-1,sizeof(head));tot=0;}
void add(int u,int v){to[++tot]=v,nxt[tot]=head[u],head[u]=tot;}
#define EOR(i,G,u) for(int i=G.head[u];~i;i=G.nxt[i])
};
Linked_list<N,N<<1>G;
Linked_list<N,N*64>fac;
int mo[N];bool mark[N];
int L[N],R[N],ori[N],ord,dep[N],fa[N],sz[N],son[N],a[N],n;
LL cnt[N],sum[N];
LL ans;
void init()
{
FOR(i,1,N-3)mo[i]=1,mark[i]=0;
FOR(i,2,N-3)if(!mark[i])
{
for(int j=i;j<=N-3;j+=i)
{
mark[j]=1;
if(j/i%i==0)mo[j]=0;
else mo[j]=-mo[j];
}
}
FOR(i,1,N-3)if(mo[i])
for(int j=i;j<=N-3;j+=i)
fac.add(j,i);
return;
}
void dfs(int u,int f,int d)
{
dep[u]=d,fa[u]=f,sz[u]=1,son[u]=0;
L[u]=++ord,ori[ord]=u;
EOR(i,G,u)
{
int v=G.to[i];
if(v==f)continue;
dfs(v,u,d+1);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v;
}
R[u]=ord;
}
void update(int l,int r,int k)
{
FOR(i,l,r)
{
int u=ori[i];
EOR(i,fac,a[u])
{
int s=fac.to[i];
cnt[s]+=k;
sum[s]+=k*dep[u];
}
}
}
void calc(int l,int r,int lca)
{
FOR(i,l,r)
{
int u=ori[i];
EOR(i,fac,a[u])
{
int s=fac.to[i];
ans+=mo[s]*(sum[s]+cnt[s]*dep[u]-2*dep[lca]*cnt[s]);
}
}
}
void dsu(int u,int f)
{
EOR(i,G,u)
{
int v=G.to[i];
if(v==f||v==son[u])continue;
相關推薦
計蒜客 青雲的機房組網方案(莫比烏斯函式+樹上dsu)
題意
給定一棵
n
n
n 個節點的樹,每個節點上有一個點權,邊權為均
BZOJ 2440 完全平方數(莫比烏斯函式+容斥)
注意的兩點是二分的時候注意,要選取最小的那個答案,因為19是13個,20也是13個,而很明顯19才是符合答案的。
還有感覺題目給的資料範圍不對,實際比較大,所以二分的時候r大點。
#include<bits/stdc++.h>
using nam
hdu6053 多校第二場(莫比烏斯函式,列舉)
之前不知道莫比烏斯反演,看了一波,然後有些許理解,這個題其實就是使用了莫比烏斯函式U的定義,詳細的解題報告這裡說的比較清楚
#include<iostream>
#include<cstdio>
#include<cmath&
LCM(i,j)求和 (莫比烏斯函式)
原題:
BZOJ2693
題意:
求∑ni=1∑mj=1lcm(i,j)∑i=1n∑j=1mlcm(i,j)
O(N)O(N)版本:
遇到lcm首先是換成gcd,Ans=∑ni=1∑mj=1i∗jgcd(i,j)Ans=∑i=1n∑j=1mi∗jg
BZOJ 3930 選數(莫比烏斯函式+杜教篩)
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#def
線性篩(尤拉函式)(莫比烏斯函式)
在這裡提供三種線性篩的講解,它們分別是:素數篩,尤拉篩和莫比烏斯篩。
·篩法正確性的重要理論依據:
上述函式均為積性函式。積性函式的性質為:若f(x)是一個積性函式,那麼對於任意素數a,b,滿足f(ab)=f(a)*f(b)
·一些可愛的要點(有助於理解篩法原理
我的第一道杜教篩(莫比烏斯函式求和 51Nod-1244)
先總結一下,杜教篩的的精髓之處我認為在於通過兩個積性函式做狄利克雷卷積以後就可以對其進行整除分塊了,又因為一般用到杜教篩的題目資料量都特別大,是o(n)時間都跑不過來的資料,所以肯定不能預處理。但是這樣的題樣例數量不會太大,你只能每一次都計算結果,不能與處理出來結果,所以你需
HDU 6053 TrickGCD(莫比烏斯函式)
題意:給出陣列 AA ,問有多個種 BB 陣列滿足所給條件。
思路
設 gcd(b1,...bn) = k (k >= 2),此時 k 對答案的貢獻為 (a1/k)*(a2/k)*(a3/k
LOJ #528. 「LibreOJ β Round #4」求和 (莫比烏斯函式)
題意
計算 ∑i=1n∑j=1mμ2(gcd(i,j))∑i=1n∑j=1mμ2(gcd(i,j)) (mod(mod 998244353)998244353)
題解
∑d=1nμ2(d)
HDU 1695 GCD (莫比烏斯反演模板)
GCD
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17212 Accepted
HDU6053 TrickGCD(莫比烏斯函式)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
/*
給定數列
HDU 6053 TrickGCD (莫比烏斯函式)
Description
You are given an array A , and Zhu wants to know there are how many different array B
hdu3501 尤拉函式(或容斥原理(莫比烏斯函式))
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=3501
題解1:顯然,本體可以用容斥原理,求出每個數的倍數情況,其係數就是莫比烏斯函式。
題解2:對於整
hdu 6134 (莫比烏斯函式,預處理快速求因子個數)
> The Death Star, known officially as the DS-1 Orbital Battle Station, also known as the Death Star I, the First Death Star, Project Stardust internally
BZOJ 2301: [HAOI2011]Problem b(莫比烏斯反演)
計算 algo cto ref blog image get txt += http://www.lydsy.com/JudgeOnline/problem.php?id=2301
題意:對於給出的n個詢問,每次求有多少個數對(x,y),滿足a≤x≤b,c&l
SPOJ - PGCD Primes in GCD Table(莫比烏斯反演)
cnblogs -s def problems 前綴和 ret mage () eof http://www.spoj.com/problems/PGCD/en/
題意:
給出a,b區間,求該區間內滿足gcd(x,y)=質數的個數。
思路:
設f(n)為 gc
hdu 1695 GCD(莫比烏斯入門)
技術分享 sin urn cas str 由於 ons pre () 題意:求a<=x<=b ,x<=y<=d,中gcd(x,y)==k的數對個數
思路:題目可以轉化成求1<=x<=b/k,1<=y<=d/k中gcd(x,y)
數論18——反演定理(莫比烏斯反演)
技術分享 滿足 urn spa isp name 角速度 我們 組成 莫比烏斯反演也是反演定理的一種
既然我們已經學了二項式反演定理
那莫比烏斯反演定理與二項式反演定理一樣,不求甚解,只求會用
莫比烏斯反演長下面這個樣子(=?ω?=)
d|n,表示
【HDU1695】GCD(莫比烏斯反演)
重復 min put clas 題解 iostream fine har clu 【HDU1695】GCD(莫比烏斯反演)
題面
題目大意
求\(a<=x<=b,c<=y<=d\)
且\(gcd(x,y)=k\)的無序數對的個數
其中,你可以假定\(
【Luogu3455】【POI2007】ZAP-Queries(莫比烏斯反演)
stream bre 似的 string 獲得 計算 getc ans contain 【Luogu3455】【POI2007】ZAP-Queries(莫比烏斯反演)
題面
題目描述
FGD正在破解一段密碼,他需要回答很多類似的問題:對於給定的整數a,b和d,有多少正整數對