传送门
N个人围绕着圆桌坐着,其中一些是男孩,另一些是女孩。你的任务是找出所有合法的方案数,使得不超过K个女孩座位是连续的。循环同构被视作同一种方案。
#include
#include
#include
#include
#define maxn 2005
#define ll long long
#define mo 100000007
using namespace std;
int T,n,k,i,j,d;
ll f[maxn],sum;
int gcd(int x,int y){return (x%y==0)?y:gcd(y,x%y);}
ll ksm(ll x,ll y){
ll s=1;
for(;y;y/=2,x=x*x%mo) if (y&1)
s=s*x%mo;
return s;
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&k);
if (k>=n) {
sum=0;
for(i=1;i<=n;i++) sum+=ksm(2,gcd(i,n));
sum%=mo;
printf("%lld\n",sum*ksm(n,mo-2)%mo);
continue;
}
memset(f,0,sizeof(f));
for(f[0]=1,i=1;i<=k;i++) f[i]=f[i-1]*2%mo;
for(i=k+1;i<=n;i++) f[i]=(f[i-1]*2-((i==k+1)?1:f[i-k-2]))%mo;
sum=0;
for(i=1;i<=n;i++){
d=gcd(i,n);
if (d<=k) {sum+=ksm(2,d)-1;continue;}
sum+=f[d];
for(j=k+1;j<d&&j<=2*k;j++)
sum-=((d-j<=2)?1:f[d-j-2])*(k-(j-k)+1)%mo;
}
printf("%lld\n",(sum%mo+mo)%mo*ksm(n,mo-2)%mo);
}
}
传送门
给2n的圆环染色,一共有m种颜色,循环同构以及对角线位置(即i与i+n)交换后相同的方案视为一种。
共有多少种不同的方案?
T(T<=2222)组数据,n,m<19260817,模19260817
#include
#include
#include
#include
#define maxn 20000000
#define mo 19260817
#define ll long long
using namespace std;
int T,i,j,k;
int tot,pri[maxn/10],bz[maxn],phi[maxn];
ll n,m,sum;
ll ksm(ll x,ll y){
ll s=1;
for(;y;y/=2,x=x*x%mo) if (y&1)
s=s*x%mo;
return s;
}
void GetPhi(){
phi[1]=1;
for(i=2;i<maxn;i++){
if (!bz[i]) pri[++tot]=i,phi[i]=i-1;
for(j=1;j<=tot&&i*pri[j]<maxn;j++) {
bz[i*pri[j]]=1;
if (i%pri[j]==0){
phi[i*pri[j]]=phi[i]*pri[j]%mo;
break;
} else phi[i*pri[j]]=phi[i]*(pri[j]-1)%mo;
}
}
}
int main(){
GetPhi();
scanf("%d",&T);
while (T--){
scanf("%lld%lld",&n,&m);
m=m*(m+1)/2%mo;
sum=0;
for(i=1;i<=sqrt(n);i++) if (n%i==0){
sum+=ksm(m,i)*phi[n/i]%mo;
if (i*i!=n) sum+=ksm(m,n/i)*phi[i]%mo;
}
printf("%lld\n",sum%mo*ksm(n,mo-2)%mo);
}
}