【WC模拟】B君的宴请
来源:互联网 发布:中央电视台直播软件 编辑:程序博客网 时间:2024/05/02 09:42
Description
求在n个点的圆环中选出k个不相邻的点的方案数。
如果两个方案能够通过旋转或对称重合则视为同一种。
n,k<=10^6
Solution
首先我们强制一个选,然后只记录两两选择点之间的数的个数。
那么原问题就转化成了把n-k划分成k个正整数的方案数,允许旋转和对称。
burnside引理直接上。
可以发现旋转之后再对称可以等同于以另一条对称轴对称。
同理对称之后再旋转也是一样的。
那么我们的置换集合的大小就为2*k,k种旋转,k种对称。
旋转就是经典问题了,枚举旋转i位,每一组相同的数的个数为k/gcd(i,k),那么我们可以直接把总和除以个数,就变成每个数只有一个的填数方案。
直接组合数计算就好了。
对称分两种情况讨论。
如果k为奇数那么对称一定经过一个选择的点,枚举被对称轴经过的那一段没选的点的个数,组合数直接算就好了。
k为偶数同理,不过有两段都不经过选择的点和两段都经过选择的点两种情况。
然后最后算出来的不动的方案数直接/2k就是答案。
Code
#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long ll;const int N=1e6+5,mo=1e9+7;int n,k,fact[N],inv[N];int gcd(int x,int y) { return y?gcd(y,x%y):x;}int mi(int x,int y) { int z=1; for(;y;y/=2,x=(ll)x*x%mo) if (y&1) z=(ll)z*x%mo; return z;}int c(int m,int n) { if (n>m||m<0||n<0) return 0; return (ll)fact[m]*inv[n]%mo*inv[m-n]%mo;}int main() { freopen("round.in","r",stdin); freopen("round.out","w",stdout); scanf("%d%d",&n,&k);n-=k; if (k<=1) { printf("1\n"); return 0; } if (k==2) { printf("%d\n",n/2); return 0; } fact[0]=inv[0]=inv[n]=1; fo(i,1,n) fact[i]=(ll)fact[i-1]*i%mo; inv[n]=mi(fact[n],mo-2); fd(i,n-1,1) inv[i]=(ll)inv[i+1]*(i+1)%mo; int ans=c(n-1,k-1); fo(i,1,k-1) { int len=k/gcd(i,k); if (!(n%len)) (ans+=c(n/len-1,k/len-1))%=mo; } if (k&1) { int res=0; fo(i,1,n-k+1) if (!((n-i)&1)) (res+=c((n-i)/2-1,k/2-1)%mo)%=mo; (ans+=(ll)res*k%mo)%=mo; } else { int res=0; if (!(n&1)) res=c(n/2-1,k/2-1); fo(i,2,n-k+2) if (!((n-i)&1)) (res+=(ll)c((n-i)/2-1,k/2-2)*(i-1)%mo)%=mo; (ans+=(ll)res*(k/2)%mo)%=mo; } printf("%lld\n",(ll)ans*mi(k*2,mo-2)%mo); return 0;}
0 0
- JZOJ4957. 【WC模拟】B君的宴请
- 【WC模拟】B君的宴请
- B君的宴请
- 【WC2017四校联考5】B君的宴请 题解
- 【WC模拟】优美的树
- 【WC模拟】覆盖的串
- JZOJ4951. 【WC模拟】优美的树
- 【WC模拟1.23】Random
- 【WC模拟】Monument
- JZOJ4944. 【WC模拟】Monument
- 【WC模拟】Monument
- JZOJ4954. 【WC模拟】Equation
- JZOJ4956. 【WC模拟】Arrangement
- 【WC模拟】Equation
- 【WC模拟】Arrangement
- 【WC模拟】J
- 12.02WC模拟题解
- 模拟linux的命令wc编写的一个函数
- linux下查询命令的技巧
- 分数树(BZOJ2651)
- Oracle数据库基本概念理解(3)
- java——求余操作%
- 中华田园犬与泰迪
- 【WC模拟】B君的宴请
- 【JZOJ4964】【GDKOI2017模拟1.21】Rhyme
- Hibernate基本概念
- SPOJ Count on a tree(lca+主席树,树上主席树,好题)
- 【LeetCode】104.Maximum Depth of Binary Tree
- 【设计模式】--代理模式 (Proxy模式)
- 7种常见排序算法-冒泡与选择
- Hibernate基本概念 (2)
- 【GDKOI2017模拟1.21】Rhyme