当前位置:网站首页>[noi simulation] Anaid's tree (Mobius inversion, exponential generating function, Ehrlich sieve, virtual tree)
[noi simulation] Anaid's tree (Mobius inversion, exponential generating function, Ehrlich sieve, virtual tree)
2022-07-05 23:57:00 【DD(XYX)】
Topic
512mb, 4s
1 ≤ n ≤ 1 0 5 , 0 ≤ K ≤ 10 , 1 ≤ u , v ≤ n 1\leq n\leq 10^5,0\leq K\leq 10,1\leq u,v\leq n 1≤n≤105,0≤K≤10,1≤u,v≤n .
Answer key
We first have this formula :
ϕ ( x y ) = ϕ ( x ) ϕ ( y ) ⋅ g c d ( x , y ) ϕ ( g c d ( x , y ) ) \phi(xy)=\phi(x)\phi(y)\cdot \frac{gcd(x,y)}{\phi(gcd(x,y))} ϕ(xy)=ϕ(x)ϕ(y)⋅ϕ(gcd(x,y))gcd(x,y)
Then you can substitute the answer
∑ i = 1 n ∑ j = 1 n ϕ ( i j ) d k ( i , j ) = ∑ i = 1 n ∑ j = 1 n ϕ ( i ) ϕ ( j ) g c d ( i , j ) ϕ ( g c d ( i , j ) ) d k ( i , j ) = ∑ g = 1 n g ϕ ( g ) ∑ i = 1 n ∑ j = 1 n ϕ ( i ) ϕ ( j ) [ g c d ( i , j ) = g ] d k ( i , j ) \sum_{i=1}^n\sum_{j=1}^n\phi(ij)d^k(i,j)=\sum_{i=1}^n\sum_{j=1}^n\phi(i)\phi(j)\frac{gcd(i,j)}{\phi(gcd(i,j))}d^k(i,j)\\ =\sum_{g=1}^n\frac{g}{\phi(g)}\sum_{i=1}^n\sum_{j=1}^n\phi(i)\phi(j)[gcd(i,j)=g]d^k(i,j)\\ i=1∑nj=1∑nϕ(ij)dk(i,j)=i=1∑nj=1∑nϕ(i)ϕ(j)ϕ(gcd(i,j))gcd(i,j)dk(i,j)=g=1∑nϕ(g)gi=1∑nj=1∑nϕ(i)ϕ(j)[gcd(i,j)=g]dk(i,j)
In this step, let's use a simple method :
= ∑ g = 1 n g ϕ ( g ) ∑ g ∣ T μ ( T / g ) ∑ T ∣ i n ∑ T ∣ j n ϕ ( i ) ϕ ( j ) d k ( i , j ) = ∑ T = 1 n ( ∑ T ∣ i n ∑ T ∣ j n ϕ ( i ) ϕ ( j ) d k ( i , j ) ) ( ∑ g ∣ T g ϕ ( g ) μ ( T / g ) ) =\sum_{g=1}^n\frac{g}{\phi(g)}\sum_{g|T}\mu(T/g)\sum_{T|i}^n\sum_{T|j}^n\phi(i)\phi(j)d^k(i,j)\\ =\sum_{T=1}^n\left(\sum_{T|i}^n\sum_{T|j}^n\phi(i)\phi(j)d^k(i,j)\right)\left(\sum_{g|T}\frac{g}{\phi(g)}\mu(T/g)\right) =g=1∑nϕ(g)gg∣T∑μ(T/g)T∣i∑nT∣j∑nϕ(i)ϕ(j)dk(i,j)=T=1∑n⎝⎛T∣i∑nT∣j∑nϕ(i)ϕ(j)dk(i,j)⎠⎞⎝⎛g∣T∑ϕ(g)gμ(T/g)⎠⎞
Then we can preprocess the lump on the right .
Violence enumeration T T T There are a total of O ( n ln n ) O(n\ln n) O(nlnn) individual . We're interested in every T T T , Take out all T T T Multiple , Build a virtual tree .
Two points A , B A,B A,B stay l c a lca lca Make a contribution to , Suppose the length of the left part is a a a , The length of the right part is b b b , How to merge the two ?
We consider that k = 0 ∼ K k=0\sim K k=0∼K Put the situation of E G F EGF EGF in , Concrete ,
F A = ∑ i = 0 K ϕ ( A ) a i ⋅ x i i ! , F B = ∑ i = 0 K ϕ ( B ) b i ⋅ x i i ! F_{A}=\sum_{i=0}^K \phi(A)a^i\cdot\frac{x^i}{i!},F_B=\sum_{i=0}^K\phi(B)b^i\cdot\frac{x^i}{i!} FA=i=0∑Kϕ(A)ai⋅i!xi,FB=i=0∑Kϕ(B)bi⋅i!xi
hold F A , F B F_A,F_B FA,FB Multiply , Convolution can get k = 0 ∼ K k=0\sim K k=0∼K Of ϕ ( i ) ϕ ( j ) d k ( i , j ) \phi(i)\phi(j)d^k(i,j) ϕ(i)ϕ(j)dk(i,j) .
therefore , Let's do the virtual tree d f s \rm dfs dfs , Process each subtree to reach each descendant E G F EGF EGF And , Merging the contributions of two subtrees will directly E G F EGF EGF Just multiply it .
take A A A Of E G F EGF EGF from a k a^k ak Extended to ( a + 1 ) k (a+1)^k (a+1)k You can roll one ∑ x i i ! \sum \frac{x^i}{i!} ∑i!xi .
Time complexity O ( n ln n ( log n + K 2 ) ) O(n\ln n(\log n+K^2)) O(nlnn(logn+K2)) .
CODE
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<random>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#pragma GCC optimize(2)
using namespace std;
#define MAXN 100005
#define LL long long
#define ULL unsigned long long
#define ENDL putchar('\n')
#define DB double
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define PR pair<int,int>
#define UIN unsigned int
int xchar() {
static const int maxn = 1000000;
static char b[maxn];
static int pos = 0,len = 0;
if(pos == len) pos = 0,len = fread(b,1,maxn,stdin);
if(pos == len) return -1;
return b[pos ++];
}
#define getchar() xchar()
inline LL read() {
LL f = 1,x = 0;int s = getchar();
while(s < '0' || s > '9') {
if(s<0)return -1;if(s=='-')f=-f;s = getchar();}
while(s >= '0' && s <= '9') {
x = (x<<1) + (x<<3) + (s^48);s = getchar();}
return f*x;
}
void putpos(LL x) {
if(!x)return ;putpos(x/10);putchar((x%10)^48);}
inline void putnum(LL x) {
if(!x) {
putchar('0');return ;}
if(x<0) putchar('-'),x = -x;
return putpos(x);
}
inline void AIput(LL x,int c) {
putnum(x);putchar(c);}
const int MOD = 998244353;
int n,m,s,o,k;
inline void MD(int &x) {
if(x>=MOD)x-=MOD;}
int inv[MAXN],fac[MAXN],invf[MAXN];
vector<int> fc[MAXN];
int p[MAXN],cnt,f[MAXN],mu[MAXN],F[MAXN],dv[MAXN],phi[MAXN];
void init(int n) {
inv[0] = inv[1] = 1;
for(int i = 2;i <= max(n,15);i ++) inv[i] = (MOD-inv[MOD%i]) *1ll* (MOD/i) % MOD;
fac[0] = invf[0] = 1;
for(int i = 1;i <= 15;i ++) {
fac[i] = fac[i-1] *1ll* i % MOD;
invf[i] = invf[i-1] *1ll* inv[i] % MOD;
}
f[1] = 1; cnt = 0; mu[1] = 1; dv[1] = 1; phi[1] = 1;
for(int i = 2;i <= n;i ++) {
if(!f[i]) {
p[++ cnt] = i;
mu[i] = -1;phi[i] = i-1;dv[i] = i*1ll*inv[i-1]%MOD;
}
for(int j = 1,nm;j <= cnt && (nm=i*p[j]) <= n;j ++) {
f[nm] = 1;
if(i % p[j] == 0) {
mu[nm] = 0; phi[nm] = phi[i]*p[j];
dv[nm] = dv[i]; break;
}
mu[nm] = -mu[i]; phi[nm] = phi[i]*phi[p[j]];
dv[nm] = dv[i] *1ll* dv[p[j]] % MOD;
}
}
for(int i = 1;i <= n;i ++) {
for(int j = i,k = 1;j <= n;j += i,k ++) {
fc[j].push_back(i);
MD(F[j] += (MOD+mu[i])*1ll*dv[k]%MOD);
}
} return ;
}
int a[MAXN],dfn[MAXN],tim;
inline bool cmp(int a,int b) {
return dfn[a] < dfn[b];}
vector<int> g[MAXN];
int d[MAXN],fa[MAXN][20];//17
void dfs0(int x,int ff) {
d[x] = d[fa[x][0] = ff] + 1; dfn[x] = ++ tim;
for(int i = 1;i <= 17;i ++) fa[x][i] = fa[fa[x][i-1]][i-1];
for(int y:g[x]) if(y != ff) dfs0(y,x);
return ;
}
int lca(int a,int b) {
if(d[a] < d[b]) swap(a,b);
if(d[a] > d[b]) for(int i = 17;i >= 0;i --) {
if(d[fa[a][i]] >= d[b]) a = fa[a][i];
} if(a == b) return a;
for(int i = 17;i >= 0;i --) {
if(fa[a][i] ^ fa[b][i]) {
a = fa[a][i]; b = fa[b][i];
}
} return fa[a][0];
}
int tg[MAXN],wt[MAXN];
int hd[MAXN],nx[MAXN<<1],v[MAXN<<1],w[MAXN<<1],cne;
void ins(int x,int y,int z) {
nx[++cne] = hd[x]; v[cne] = y; hd[x] = cne; w[cne] = z;
}
struct vec{
int s[11];
vec(){
memset(s,0,sizeof(s));}
vec(int d) {
for(int i = 0,p = 1;i <= m;i ++,p = p*1ll*d%MOD)
s[i] = p*1ll*invf[i] % MOD;
}
}dp[MAXN];
inline vec operator * (vec a,vec b) {
for(int i = m;i >= 0;i --) {
int nm = 0;
for(int j = 0;j <= i;j ++) {
nm = (nm + a.s[i-j]*1ll*b.s[j]) % MOD;
} a.s[i] = nm;
} return a;
}
inline vec& operator *= (vec &a,vec b) {
for(int i = m;i >= 0;i --) {
int nm = 0;
for(int j = 0;j <= i;j ++) {
nm = (nm + a.s[i-j]*1ll*b.s[j]) % MOD;
} a.s[i] = nm;
} return a;
}
inline vec& operator += (vec &a,vec b) {
for(int i = 0;i <= m;i ++) {
MD(a.s[i] += b.s[i]);
} return a;
}
vec as;
void dfs(int x,int ff) {
dp[x] = vec(); MD(dp[x].s[0] += wt[x]);
MD(as.s[0] += wt[x]*1ll*wt[x]%MOD*inv[2]%MOD);
for(int i = hd[x];i;i = nx[i]) {
int y = v[i]; if(y == ff) continue;
dfs(y,x); dp[y] *= vec(w[i]);
as += dp[x] * dp[y];
for(int j = 0;j <= m;j ++) MD(dp[x].s[j] += dp[y].s[j]);
}
return ;
}
int st[MAXN],tp;
int main() {
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
n = read(); m = read();
init(n);
for(int i = 1;i < n;i ++) {
s = read();o = read();
g[s].push_back(o);
g[o].push_back(s);
}
dfs0(1,0);
vec ans;
for(int D = 1;D <= n;D ++) {
int cn = 0; cne = 0;
for(int j = D;j <= n;j += D) {
a[++ cn] = j; wt[j] = phi[j];
tg[j] = D; hd[j] = 0;
}
sort(a + 1,a + 1 + cn,cmp);
st[tp = 1] = a[1];
for(int i = 1;i <= cn;i ++) {
int x = a[i],lc = lca(x,st[tp]),p = 0;
if(tg[lc] != D) {
tg[lc] = D; wt[lc] = hd[lc] = 0;
}
while(tp > 0 && d[st[tp]] > d[lc]) {
if(p) ins(st[tp],p,d[p]-d[st[tp]]);
p = st[tp --];
}
if(p) ins(lc,p,d[p] - d[lc]);
if(st[tp] != lc) st[++ tp] = lc;
if(x != lc) st[++ tp] = x;
}
int p = 0;
while(tp > 0) {
if(p) ins(st[tp],p,d[p]-d[st[tp]]);
p = st[tp --];
}
as = vec();
dfs(p,0);
for(int i = 0;i <= m;i ++) as.s[i] = as.s[i] *2ll* F[D] % MOD;
ans += as;
}
for(int i = 0;i <= m;i ++) {
AIput(ans.s[i]*1ll*fac[i]%MOD,'\n');
}
return 0;
}
边栏推荐
- 20220703 周赛:知道秘密的人数-动规(题解)
- Open source CRM customer relationship system management system source code, free sharing
- Bao Yan notes II software engineering and calculation volume II (Chapter 13-16)
- 亲测可用fiddler手机抓包配置代理后没有网络
- 选择致敬持续奋斗背后的精神——对话威尔价值观【第四期】
- VBA fast switching sheet
- The use of El cascader and the solution of error reporting
- Wechat applet -- wxml template syntax (with notes)
- Upgrade openssl-1.1.1p for openssl-1.0.2k
- 提升工作效率工具:SQL批量生成工具思想
猜你喜欢
选择致敬持续奋斗背后的精神——对话威尔价值观【第四期】
PV static creation and dynamic creation
QT QPushButton details
用列表初始化你的vector&&initializer_list简介
【NOI模拟赛】Anaid 的树(莫比乌斯反演,指数型生成函数,埃氏筛,虚树)
Tips for using pads router
My colleagues quietly told me that flying Book notification can still play like this
【LeetCode】5. Valid palindrome
【在线聊天】原来微信小程序也能回复Facebook主页消息!
Spire Office 7.5.4 for NET
随机推荐
[online chat] the original wechat applet can also reply to Facebook homepage messages!
7.5模拟赛总结
Online yaml to CSV tool
Huawei equipment is configured with OSPF and BFD linkage
C reflection and type
C # input how many cards are there in each of the four colors.
Detailed explanation of APP functions of door-to-door appointment service
Spreadjs 15.1 CN and spreadjs 15.1 en
DEJA_VU3D - Cesium功能集 之 055-国内外各厂商地图服务地址汇总说明
云呐|固定资产管理系统主要操作流程有哪些
什么叫做信息安全?包含哪些内容?与网络安全有什么区别?
20. Migrate freetype font library
Qcombox (rewrite) + qcompleter (auto completion, auto loading the drop-down options of qcombox, setting the background color)
如何获取localStorage中存储的所有值
What is a humble but profitable sideline?
妙才周刊 - 8
Qt 一个简单的word文档编辑器
Problems encountered in the database
Doppler effect (Doppler shift)
The difference of time zone and the time library of go language