「CF757E」 Bash Plays with Functions
题意
设 \(\omega(n)\) 表示 \(n\) 的质因子个数,定义
给出 \(q\) 个 \(r,n\),求出 \(f_r(n)\) 的值。
分析
先考虑 \(r=0\) 的情况,因为 \(p,q\) 互质,所以两数没有共同质因子,答案即把 \(\omega(n)\) 个质因子分成两份的方案数,答案为 \(2^{\omega(n)}\)。
考虑 \(r=1\) 的情况,由唯一分解定理,\(n=p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}(p_i\in\mathbb{P})\),则 \(f_1(n)=\sum\limits_{d|n}f_0(d)\),由 \(f_0(d)=2^{\omega(d)}\) 为积性函数,考虑把每个 \(d\) 分解成这些质因子,可得 \(f_1(n)=f_1(p_1^{a_1})f_1(p_2^{a_2})\cdots f_1(p_k^{a_k})\),所以 \(f_1(n)\) 也是积性函数。
当 \(r>1\) 时,因为不要求分出来的两个数互质,把式子展开得 \(f_r(n)=\sum f_{r-1}(p_1^{b_1}p_2^{b_2}\cdots p_k^{b_k})\),其中 \(b_i\in[0,a_i]\),且所有数互不相同,那这样就是一个多项式乘法的形式,由 \(f_r(p_i^{a_i})=\sum\limits_{j=0}^{a_i}f_{r-1}(p_i^{j})\),得到同上的式子,所以 \(f_r(n)\) 为积性函数。
可以发现 \(f_r(p_i^{a_i})\) 的值与 \(p_i\) 的大小没有关系,可以递推求 \(r,b_i\) 固定的函数值,因为 \(n\le 10^6\),所以 \(b_i<20\),可以递推预处理。
询问时用积性函数的性质把 \(n\) 分解,求质因子函数值的乘积即可。但是 \(\sqrt n\) 直接分解太慢了,可以先筛出 \([2,10^6]\) 的最大质因子,分解时除这个因子,统计次数,这样最多是 \(O(\log n)\) 的。
复杂度 \(O(20r+q\log n)\)。
Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
// static char buf[100],*p1=buf,*p2=buf,obuf[100],*p3=obuf;
// #define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++
// #define putchar(x) (p3-obuf<100)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());
#define dbg(x) cout<<#x<<": "<<x<<"\n"
#define usetime() printf("time: %.3lfs\n",clock()*1.0/CLOCKS_PER_SEC)
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}short top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');}
namespace tobe{
const ll maxn=1e6+5,mod=1e9+7;
ll q,r,n,f[maxn][20],mx[maxn];
bitset<maxn>vis;
inline void mian(){
f[0][0]=1;
for(ll i=1;i<20;++i)f[0][i]=2;
for(ll i=1;i<=1e6;++i){
ll sum=0;
for(ll j=0;j<20;++j){
sum=(sum+f[i-1][j])%mod;
f[i][j]=sum;
}
}
for(ll i=2;i<=1e6;++i){
if(vis[i])continue;
for(ll j=i;j<=1e6;j+=i){
mx[j]=i,vis.set(j);
}
}
q=read();
while(q--){
r=read(),n=read();
ll ans=1;
while(n>1){
ll now=mx[n],cnt=0;
while(n%now==0)++cnt,n/=now;
ans=ans*f[r][cnt]%mod;
}
write(ans);
}
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ll t=1;
while(t--)tobe::mian();
// fwrite(obuf,p3-obuf,1,stdout);
return 0;
}

浙公网安备 33010602011771号