bzoj4305 数学
来源:互联网 发布:mac imovie 丢失 编辑:程序博客网 时间:2024/05/19 17:56
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4305
大意:给长度为n的数列a,求有多少种数列b满足:
1、1<=b[i]<=m
2、 gcd(b[1],b[2],…,b[n])=d(d=1,2,3,…,m)
3、[ai≠bi]的个数为k
可以参考popoqqq blog
k个不同可以转为n-k个相同。
用cnt表示数列a中有多少个是d的倍数。
ans[d]=C(cnt,k)(m/d-1)^(cnt-k)(m/d)^(n-cnt)-ans[d*i].
(m/d-1)^(cnt-k)表示cnt中除去相同的可以选的方案
(m/d)^(n-cnt)表示除去cnt剩下的项可以选的个数
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int mm=int(1e9)+7;int n,m,K,ans[300050],a[300050],cnt;int Pow[300050],Inv[300050];inline int Mod(int x,int y){ x+=y; if (x>=mm) x-=mm; return x;}inline int ksm(int x,int y){ long long r=1; for (;y;y>>=1,x=1ll*x*x%mm) if (y&1) r=r*x%mm; return r;}inline int jc(int a,int b){ return 1ll*Pow[a]*Inv[b]%mm*Inv[a-b]%mm;}int main(){ scanf("%d%d%d",&n,&m,&K); K=n-K; int x; for (int i=1;i<=n;++i) { scanf("%d",&x); ++a[x]; } Pow[0]=1; for (int i=1;i<=n;++i) Pow[i]=1ll*Pow[i-1]*i%mm; Inv[n]=ksm(Pow[n],mm-2); for (int i=n-1;i>=0;--i) Inv[i]=1ll*Inv[i+1]*(i+1)%mm; for (int i=m;i;--i) { cnt=0; for (int j=1;1ll*i*j<=m;++j) cnt+=a[i*j]; if (cnt<K) continue; ans[i]=1ll*jc(cnt,K)*ksm(m/i-1,cnt-K)%mm*ksm(m/i,n-cnt)%mm; } for (int i=m;i;--i) for (int j=i+i;j<=m;j+=i) ans[i]=Mod(ans[i],mm-ans[j]); for (int i=1;i<m;++i) printf("%d ",ans[i]); printf("%d\n",ans[m]);}
0 0
- bzoj4305 数学
- 【BZOJ4305】数列的GCD
- 【bzoj4305】数列的GCD
- [bzoj4305]数列的gcd
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- 数学
- C语言之反序数组和求最大值和最小值
- 【android基础二】android重要控件——你有多熟悉listview?
- Map集合
- STM32F207(4) 上电关中断
- R和JSON的傻瓜式编程
- bzoj4305 数学
- bzoj 1690: [Usaco2007 Dec]奶牛的旅行
- 【spring模拟】IOC描述及模拟
- Java基础-实现文件搜索功能
- (二)H264语法及结构
- CentOS(6.5)安装lsb、查看系统版本信息
- catalina.out
- Android学习(一)TextView,ImageView,Button,EditText,控件
- Develop--Training(七)Getting Started--支持不同的设备