正题
题目链接:https://www.luogu.com.cn/problem/P3172
题目大意
求有多少个长度为NNN的值域在[L,R][L,R][L,R]这个区间的序列满足它们的gcdgcdgcd恰好是KKK。
解题思路
dpdpdp容斥思想
我们先让L=⌊L+K−1K⌋,R=⌊RK⌋L=\lfloor\frac{L+K-1}{K}\rfloor,R=\lfloor\frac{R}{K}\rfloorL=⌊KL+K−1⌋,R=⌊KR⌋,这样就变成了让gcdgcdgcd是111。
然后设fif_{i}fi表示gcdgcdgcd恰好是iii时的方案。开始时,若对于一个iii有xxx个数在[L,R][L,R][L,R]的区间内,那么fi=xn−xf_i=x^n-xfi=xn−x表示这个区间的公约数包含xxx且不完全相同时的方案数,那么我们让所有的fif_ifi减去fk∗i(k∗i≤R−L)f_{k*i}(k*i\leq R-L)fk∗i(k∗i≤R−L)的最终值即可。
注意当L=1L=1L=1时需要特判,因为可以全是111。
杜教筛+莫比乌斯反演思想
这里只是提及一下,我也没写
定义f(x)f(x)f(x)表示gcdgcdgcd为xxx时的方案数,ct(l,r,k)ct(l,r,k)ct(l,r,k)表示[l,r][l,r][l,r]区间kkk的倍数的个数
那么F(x)=∑x∣df(d)=ct(L,R,x)nF(x)=\sum_{x|d}f(d)=ct(L,R,x)^nF(x)=x∣d∑f(d)=ct(L,R,x)n
f(k)=∑k∣dF(dk)μ(d)=∑i=1⌊Rk⌋F(ik)μ(i)f(k)=\sum_{k|d}F(\frac{d}{k})\mu(d)=\sum_{i=1}^{\lfloor\frac{R}{k}\rfloor}F(ik)\mu(i)f(k)=k∣d∑F(kd)μ(d)=i=1∑⌊kR⌋F(ik)μ(i)
展开ctctct
⇒f(k)=∑i=1⌊Rk⌋(⌊Rik⌋−⌊L−1ik⌋)μ(i)\Rightarrow f(k)=\sum_{i=1}^{\lfloor\frac{R}{k}\rfloor}(\lfloor\frac{R}{ik}\rfloor-\lfloor\frac{L-1}{ik}\rfloor)\mu(i)⇒f(k)=i=1∑⌊kR⌋(⌊ikR⌋−⌊ikL−1⌋)μ(i)
然后整除分块前面那一部分,后面那一部分杜教筛处理即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll P=1e9+7;
ll n,k,w,h,f[110000];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
int main()
{scanf("%lld%lld%lld%lld",&n,&k,&w,&h);w=(w+k-1)/k;h=h/k;if(h<w)return printf("0")&0;for(ll i=1;i<=h-w;i++){ll x=h/i-(w+i-1)/i+1;if(x<=0)continue;f[i]=(power(x,n)-x+P)%P;}for(ll i=h-w;i>=1;i--)for(ll j=2*i;j<=h-w;j+=i)f[i]=(f[i]-f[j]+P)%P;if(w==1)f[1]=(f[1]+1)%P;printf("%lld\n",f[1]);return 0;
}