【题目地址】
题意简述
给你 n , d n,d n,d,求下面式子在 m o d 1 0 9 + 7 {\rm mod}\ 10^9+7 mod 109+7意义下的值。
∑ i = 1 n [ g c d ( i , n ) = 1 ] i d \sum_{i=1}^n[gcd(i,n)=1]i^d i=1∑n[gcd(i,n)=1]id
其中 n n n特别大,所以我们给你一个 w w w,然后给你两个数组 p i , c i p_i,c_i pi,ci,其中:
n = ∏ i = 1 w p i c i n=\prod_{i=1}^wp_i^{c_i} n=i=1∏wpici
d ≤ 100 , w ≤ 1000 , p i , c i ≤ 1 0 9 d\leq 100,w\leq 1000,p_i,c_i\leq 10^9 d≤100,w≤1000,pi,ci≤109
我们仍旧先推一波式子:
a n s = ∑ i = 1 n [ g c d ( i , n ) = 1 ] i d = ∑ i = 1 n i d ∑ j ∣ i , j ∣ n μ ( j ) = ∑ j = 1 n μ ( j ) ∑ j ∣ i n i d = ∑ j = 1 n μ ( j ) ∑ i = 1 ⌊ n j ⌋ ( i j ) d = ∑ j = 1 n μ ( j ) j d ∑ i = 1 ⌊ n j ⌋ i d \begin{aligned} ans=&\sum_{i=1}^n[gcd(i,n)=1]i^d \\ =& \sum_{i=1}^ni^d\sum_{j|i,j|n}\mu(j) \\ =& \sum_{j=1}^n\mu(j)\sum_{j|i}^ni^d \\ =& \sum_{j=1}^n\mu(j)\sum_{i=1}^{\lfloor\frac{n}{j}\rfloor}(ij)^d \\ =&\sum_{j=1}^n\mu(j)j^d\sum_{i=1}^{\lfloor\frac{n}{j}\rfloor}i^d \end{aligned} ans=====i=1∑n[gcd(i,n)=1]idi=1∑nidj∣i,j∣n∑μ(j)j=1∑nμ(j)j∣i∑nidj=1∑nμ(j)i=1∑⌊jn⌋(ij)dj=1∑nμ(j)jdi=1∑⌊jn⌋id
后面部分就是自然数幂的前缀和,拉格朗日差值就可以了,在 O ( d l o g d ) O(dlogd) O(dlogd)时间内求出,而前面是可以杜教筛的:
∑ j ∣ n μ ( j ) j d = ( μ ⋅ i d d ) ∗ 1 \begin{aligned} \sum_{j|n}\mu(j)j^d=&(\mu\cdot id^d)*\mathbf1 \end{aligned} j∣n∑μ(j)jd=(μ⋅idd)∗1
我们令 f = ( μ ⋅ i d d ) ∗ 1 , g = i d d f=(\mu\cdot id^d)*\mathbf1,g=id^d f=(μ⋅idd)∗1,g=idd,然后 f ∗ g f*g f∗g就等于:
∑ j ∣ n μ ( j ) j d ( n j ) d = n d ∑ j ∣ n μ ( j ) = n d [ n = 1 ] = [ n = 1 ] = ϵ \sum_{j|n}\mu(j)j^d(\frac{n}{j})^d=n^d\sum_{j|n}\mu(j)=n^d[n=1]=[n=1]=\epsilon j∣n∑μ(j)jd(jn)d=ndj∣n∑μ(j)=nd[n=1]=[n=1]=ϵ
所以 f = ( μ ⋅ i d d ) ∗ 1 , g = i d d , h = ϵ f=(\mu\cdot id^d)*\mathbf1,g=id^d,h=\epsilon f=(μ⋅idd)∗1,g=idd,h=ϵ,然后套入杜教筛公式即可:
S ( n ) = 1 − ∑ i = 2 n i d S ( ⌊ n i ⌋ ) S(n)=1-\sum_{i=2}^ni^dS(\lfloor\frac{n}{i}\rfloor) S(n)=1−i=2∑nidS(⌊in⌋)
然后就可以在 O ( n 2 3 d l o g d ) O(n^{\frac{2}{3}}dlogd) O(n32dlogd)的时间内解决了。
等等, n n n好像有 1 0 10000... 10^{10000...} 1010000...左右,-_-||。
但是不是就这样束手就擒,打暴力去了呢?
不,我们离正解还差一步了。
但是,我们根据拉格朗日差值的经验可以知道, ∑ i = 1 n i d \sum_{i=1}^ni^d ∑i=1nid为一个 d + 1 d+1 d+1次多项式,那么我们令 g ( x ) = ∑ i = 1 x i d g(x)=\sum_{i=1}^xi^d g(x)=∑i=1xid,同时我们也可以知道 g ( x ) = ∑ i = 1 d + 1 a i x i g(x)=\sum_{i=1}^{d+1}a_ix^i g(x)=∑i=1d+1aixi,假设我们求出了所有 a i a_i ai,我们将其带入式子,看看有没有什么奇妙的反应:
a n s = ∑ j = 1 n μ ( j ) j d ∑ i = 1 ⌊ n j ⌋ i d = ∑ j = 1 n μ ( j ) j d ∑ i = 1 d + 1 a i ( ⌊ n j ⌋ ) i = ∑ i = 1 d + 1 a i ∑ j ∣ n μ ( j ) j d ( ⌊ n j ⌋ ) i \begin{aligned} ans=&\sum_{j=1}^n\mu(j)j^d\sum_{i=1}^{\lfloor\frac{n}{j}\rfloor}i^d \\ =&\sum_{j=1}^n\mu(j)j^d\sum_{i=1}^{d+1}a_i\left(\left\lfloor\frac{n}{j}\right\rfloor\right)^i \\ =&\sum_{i=1}^{d+1}a_i\sum_{j|n}\mu(j)j^d\left(\left\lfloor\frac{n}{j}\right\rfloor\right)^i \end{aligned} ans===j=1∑nμ(j)jdi=1∑⌊jn⌋idj=1∑nμ(j)jdi=1∑d+1ai(⌊jn⌋)ii=1∑d+1aij∣n∑μ(j)jd(⌊jn⌋)i
现在我们主要是要解决后半部分的快速求法,我们令 f ( i ) = ∑ j ∣ n μ ( j ) j d ( ⌊ n j ⌋ ) i f(i)=\sum_{j|n}\mu(j)j^d\left(\left\lfloor\frac{n}{j}\right\rfloor\right)^i f(i)=∑j∣nμ(j)jd(⌊jn⌋)i,那么我们知道 f = ( μ ⋅ i d d ) ∗ i d i f=(\mu\cdot id^d)*id^i f=(μ⋅idd)∗idi,那么根据 μ , i d k \mu,id^k μ,idk都为积性函数,而积性函数的狄利克雷卷积都为积性函数,所以我们可以知道 f f f也是一个积性函数。
这里,我们看,题目都将
n
n
n的质因数帮我们分解好了凯森(ノ ̄▽ ̄),所以我们将质因数分开考虑,因为
f
(
n
)
=
∏
f
(
p
i
c
i
)
f(n)=\prod f(p_i^{c_i})
f(n)=∏f(pici),所以此时,我们只需知道
f
(
p
c
)
f(p^c)
f(pc)如何计算:
我们看原式
∑
j
∣
p
c
μ
(
j
)
j
d
(
⌊
n
j
⌋
)
i
=
∑
k
=
0
c
μ
(
p
k
)
(
p
k
)
d
(
⌊
n
p
k
⌋
)
i
\sum_{j|p^c}\mu(j)j^d\left(\left\lfloor\frac{n}{j}\right\rfloor\right)^i=\sum_{k=0}^c\mu(p^k)(p^k)^d\left(\left\lfloor\frac{n}{p^k}\right\rfloor\right)^i
j∣pc∑μ(j)jd(⌊jn⌋)i=k=0∑cμ(pk)(pk)d(⌊pkn⌋)i
而根据 μ \mu μ的定义,我们知道当 k > 1 k>1 k>1时的时候 μ ( p k ) = 0 \mu(p^k)=0 μ(pk)=0,所以 k = 0 , 1 k=0,1 k=0,1,那么 f ( p c ) f(p^c) f(pc)就等于:
( p c ) i − p d ( p c − 1 ) i = p c i − p c i − i + d (p^c)^i-p^d(p^{c-1})^i=p^{ci}-p^{ci-i+d} (pc)i−pd(pc−1)i=pci−pci−i+d
那么枚举 a i a_i ai,然后枚举 p j p_j pj,然后算就用快速幂,复杂度就是 O ( d w l o g ( 1 0 9 + 6 ) ) O(dwlog(10^9+6)) O(dwlog(109+6))(因为根据欧拉定理和费马小定理,我们可以将指数 m o d 1 0 9 + 6 {\rm mod}\ 10^9+6 mod 109+6)。
好啦,就解决啦!ヾ(@^▽^@)ノ
等等辣QAQ, a i a_i ai好像还没说怎么求-_-||。
其实,我们知道它是一个 d + 1 d+1 d+1次多项式的系数,那么高斯消元就好啦,我们列出 g ( 1 ) ∼ g ( d + 1 ) g(1)\sim g(d+1) g(1)∼g(d+1)的方程即可。
前面回顾: g ( x ) = ∑ i = 1 d + 1 a i x i g(x)=\sum_{i=1}^{d+1}a_ix^i g(x)=∑i=1d+1aixi
这个方程组的初始化,我们每次枚举 x x x,然后用快速幂计算出当前的 g ( x ) g(x) g(x)的值,然后枚举 a i a_i ai,依次计算出 x i x^i xi作为系数即可,然后就是高斯消元板子啦~~
丑陋的加调了半天的代码_(¦3」∠)_:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e3+10,M=1e2+10;
const ll Mod=1e9+7;
int d,w;
ll fpow(ll a,ll b){
ll res=1;
for(;b;b>>=1,a=(a*a)%Mod)
if(b&1)res=(res*a)%Mod;
return res;
}
ll A[M][M],X[M],P[N],C[N];
void Guass(){
int D=d+1;
for(ll i=0,sum=0,x;i<=D;i++){
x=1;sum=(sum+fpow(i,d))%Mod;
A[i][D+1]=sum;
for(ll j=0;j<=D;j++){
A[i][j]=x;x=(x*i)%Mod;
}
}
for(int now=0,pos;now<=D;now++){
pos=now;
if(!A[pos][now])
for(int i=now+1;i<=D;i++)
if(A[i][now]){pos=i;break;}
if(pos!=now)swap(A[now],A[pos]);
ll inv=fpow(A[now][now],Mod-2);
for(int i=now+1;i<=D;i++){
ll tt=(A[i][now]*inv)%Mod;
for(int j=0;j<=D+1;j++){
A[i][j]=(A[i][j]-A[now][j]*tt%Mod)%Mod;
if(A[i][j]<0)A[i][j]+=Mod;
}
}
}
for(int i=D;i>=0;i--){
for(int j=D;j>=i+1;j--){
A[i][D+1]=(A[i][D+1]-A[i][j]*X[j]%Mod)%Mod;
if(A[i][D+1]<0)A[i][D+1]+=Mod;
}
X[i]=A[i][D+1]*fpow(A[i][i],Mod-2)%Mod;
}
}
ll GetH(ll a,ll b){
ll p1=C[b]*a%(Mod-1);
ll p2=(p1+d-a)%(Mod-1);if(p2<0)p2+=(Mod-1);
ll ans=(fpow(P[b],p1)-fpow(P[b],p2))%Mod;
if(ans<0)ans+=Mod;
return ans;
}
ll ans;
int main(){
scanf("%d%d",&d,&w);
Guass();
for(int i=1;i<=w;i++)scanf("%lld%lld",&P[i],&C[i]);
for(int i=0,D=d+1;i<=D;i++){
ll xx=X[i];
for(int j=1;j<=w;j++)xx=(xx*GetH(i,j))%Mod;
ans=(ans+xx)%Mod;
}
printf("%lld\n",ans);
return 0;
}
End
元旦节只放一天,1月1日还要在学校度过,惨兮兮QWQ