题目链接 http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf
B题 数论题 h(n)=∑ d|n φ(d) × n /d 求一个数的h值 我们只要意识到他是一个积性函数就解决了 这个函数看起来很像狄利克雷卷积 我们构造一个函数f(n)=n;h(n)=∑ d|n φ(d) × f(n /d)
欧拉函数φ是积性函数 构造的f是完全积性函数 所以他们的狄利克雷卷积h也是积性函数 然后推导一下答案就是 ∑(pi^qi+(pi-1)*qi*pi^(qi-1)) (1<=i<=m)
其实当你没有意识到他是一个积性函数 推导的时候也可以发现他可以用组合情况写 这就用到了子集生成知识了很简单一个dfs就可以了 m最大20 子集个数最大就是2^20 可以接受
然后枚举子集就可以得到结果了
关于 积性函数和狄利克雷卷积推荐几个博客 https://www.cnblogs.com/jianglangcaijin/p/6035766.html#undefined
https://blog.csdn.net/liyizhixl/article/details/79997478
https://www.cnblogs.com/wfj2048/p/6537861.html
积性函数性质
1.若n=pa11pa22pa33...pannn=p1a1p2a2p3a3...pnan,那么f(n)=f(pa11)f(pa22)f(pa33)...f(pann)f(n)=f(p1a1)f(p2a2)f(p3a3)...f(pnan)。
2.若ff为积性函数且有f(pn)=fn(p)f(pn)=fn(p),那么ff为完全积性函数。
狄利克雷卷积性质:
- (f∗g)=∑d|nf(d)g(nd)(f∗g)=∑d|nf(d)g(nd)
- f∗(g∗h)=(f∗g)∗hf∗(g∗h)=(f∗g)∗h
- f∗(g+h)=f∗g+f∗hf∗(g+h)=f∗g+f∗h
- f∗g=g∗f
位向量法子集生成模板 O(n*2^n)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2e5+10,M = 1000000007; 4 typedef long long ll; 5 int a[maxn],b[maxn]; 6 void print_subset(int n, int b[],int cur) 7 { 8 if(cur==n) 9 { 10 for(int i=0;i<cur;i++) 11 { 12 if(b[i]) 13 printf("%d ",a[i]); 14 } 15 printf(" "); 16 return; 17 } 18 b[cur]=1; 19 print_subset(n,b,cur+1); 20 b[cur]=0; 21 print_subset(n,b,cur+1); 22 } 23 int main() 24 { 25 int n; 26 cin>>n; 27 for(int i=0;i<n;i++) 28 a[i]=i+1; 29 memcpy(b,a,sizeof(a)); 30 print_subset(n,b,0); //传参后会修改b的值 所以copy一个数组 31 }
AC代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5+10 ,mod = 998244353; 4 typedef long long ll; 5 ll poww(ll a,ll b) 6 { 7 ll ans=1; 8 while(b>0) 9 { 10 if(b&1) 11 ans=(ans*a)%mod; 12 b=b>>1; 13 a=(a*a)%mod; 14 } 15 return ans; 16 } 17 int main() 18 { 19 int t; 20 cin>>t; 21 while(t--) 22 { 23 ll q,p,ans=1; 24 int m; 25 cin>>m; 26 while(m--) 27 { 28 cin>>p>>q; 29 ll temp=1; 30 temp=(temp*(p-1))%mod; 31 temp=(temp*q)%mod; 32 temp=(temp*poww(p,q-1))%mod; 33 temp=(temp+poww(p,q))%mod; 34 ans=ans*temp%mod; 35 //cout<<ans<<endl; 36 } 37 cout<<ans<<endl; 38 } 39 }