组合数问题
2016-11-30 14:13
211 查看
组合数问题
input:problem.in output:problem.outTime Limits: 1000 ms Memory Limits: 521MB
Description
Input
Output
Sample Input
Input1:
1 2 3 3
Input2:
2 5 4 5 6 7
Sample Output
Output1:
1
Output2:
0 7
Hint
第一个数据样例说明
Data Constraint
解题思路
很明显的前缀和题目,别告诉我你不知道这一点:
假设杨辉三角的首行为第0行,每行首个为第0个,则第i行第j个为Cij
杨辉三角对于k取模,则模为零的Cji 能被k整除
设pref[i][j] 表示满足k|Cqp(p∈[1,i],q∈[1,j],p>=q)的个数,
sum[i]=pref[i][i]
则对于给出的n,m,如果n<=m,则ans=s
否则ans=sum[m]+pref
[m]-pref[m][m]
很明显啊
不拿100对不起人了!
#include<cstring> #include<cstdio> using namespace std; int yh[2001][2001],pr[2001][2001],sum[2001],n,m,t,k; void init() { for(int i=0;i<=2000;i++) { yh[i][0]=yh[i][i]=1%k; for(int j=1;j<i;j++)yh[i][j]=(yh[i-1][j-1]+yh[i-1][j])%k; } for(int i=1;i<=2000;i++) { for(int j=1;j<=2000;j++) { if(j<=i)if(!yh[i][j])pr[i][j]=1; pr[i][j]+=pr[i][j-1]+pr[i-1][j]-pr[i-1][j-1]; } sum[i]=pr[i][i]; } } int main() { freopen("problem.in","r",stdin); freopen("problem.out","w",stdout); scanf("%d %d\n",&t,&k); init(); while(t--) { scanf("%d %d\n",&n,&m); if(n<=m)printf("%d\n",sum );else printf("%d\n",sum[m]+pr [m]-pr[m][m]); } }
其实你也可以打质因数分解的:
#include<cstring> #include<cstdio> using namespace std; int prime[2010],num[2010],p[2010],n,kk,t,m,sum[2010],pref[2010][2010],so[2010],nu[2010]; bool bz[2010],q; void init() { for(int i=2;i<=2000;i++)/*素数线性筛法*/ { if(!bz[i]) { prime[++prime[0]]=i; } for(int j=1;j<=prime[0];j++) { if(i*prime[j]>2000)break; bz[i*prime[j]]=1; if(i%prime[j]==0)break; } } int temp=kk; for(int i=1;i<=prime[0];i++)/*将k分解质因数*/ { if(temp==1)break; if(temp%prime[i]==0) { while(temp%prime[i]==0) { temp/=prime[i]; p[prime[i]]++; } so[++so[0]]=prime[i]; } } for(int i=1;i<=2000;i++) { temp=i; for(int j=1;j<=so[0];j++) { if(temp==1)break; if(!bz[temp]) { num[temp]++; temp=1; } if(temp==1)break; if(temp%so[j]==0) { while(temp%so[j]==0)temp/=so[j],num[so[j]]++; } } for(int j=1;j<=so[0];j++)nu[so[j]]=-num[so[j]]; for(int j=1;j<=2000;j++) { if(i>=j) { temp=j; for(int k=1;k<=so[0];k++) { if(temp==1)break; if(!bz[temp]) { nu[temp]--; temp=1; } if(temp==1)break; if(temp%so[k]==0) { while(temp%so[k]==0)temp/=so[k],nu[so[k]]--; } } temp=i-j+1; for(int k=1;k<=so[0];k++) { if(temp==1)break; if(!bz[temp]) { nu[temp]++; temp=1; } if(temp==1)break; if(temp%so[k]==0) { while(temp%so[k]==0)temp/=so[k],nu[so[k]]++; } } q=1; for(int k=1;k<=so[0];k++) if(num[so[k]]+nu[so[k]]<p[so[k]]) { q=0;break; } if(q)pref[i][j]=1; } pref[i][j]+=pref[i-1][j]+pref[i][j-1]-pref[i-1][j-1]; } sum[i]=pref[i][i]; } } int main() { freopen("problem.in","r",stdin); freopen("problem.out","w",stdout); scanf("%d%d",&t,&kk); init(); for(int i=1;i<=t;i++) { scanf("%d%d",&n,&m); int ans; if(n>m) { ans=sum[m]+pref [m]-pref[m][m]; }else { ans=sum ; } printf("%d\n",ans); } }
相关文章推荐
- 组合数问题 NOIP 2016 Day2 T1
- bzoj 4737: 组合数问题
- Noip2016day2 组合数问题problem
- BZOJ 4870 [Shoi2017]组合数问题 ——动态规划 矩阵乘法
- 组合数问题(NOIP2016)
- [NOIP2016D2T1]组合数问题
- bzoj P4870: [Shoi2017]组合数问题——solution
- NOIP--组合数问题(数位DP+二维前缀和数组优化)
- UOJ263 【NOIP2016】组合数问题
- NOIP2016 组合数问题
- 【NOIP2016】组合数问题
- [BZOJ4870][SHOI2017]组合数问题 DP+矩阵快速幂
- 洛谷 P2822 组合数问题
- dp——洛谷P2822 组合数问题
- BZOJ4870 [六省联考2017] 组合数问题 【快速幂】
- uoj275. 【清华集训2016】组合数问题
- 洛谷2822(NOIP2016)[组合数问题]--杨辉三角
- 【NOIP2016】D2 T1 组合数问题
- UOJ275 [清华集训2016] 组合数问题 【Lucas定理】【数位DP】
- BZOJ4870: [Shoi2017]组合数问题