标签:
Time Limit: 5000MS | Memory Limit: 65536KB | 64bit IO Format: %lld & %llu |
Description
Input
Output
Sample Input
3 2
Sample Output
1
2
Source
对于一个数列,每次求出相邻两个数之和得到一个新数列。最后结果将变成一个数。问这个数除以m的余数与原数列中哪些项无关?
分析可知若该数的系数是m的倍数,则无关。
而数列的系数是杨辉三角第n-1层的各个数字。
问题转化成求组合数C(n-1, 0)~C(n-1, n-1)中能够被m整除的个数。
将m分解质因数,记录每个因数出现的次数,然后再将c分解质因数,若c对应因数出现的次数都大于等于m,则c是m的倍数。
递推即可。
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=200001; 9 int pri[mxn],cnt=0; 10 int t[mxn]; 11 int c[mxn]; 12 int ans[mxn],num=0; 13 bool flag=0; 14 int n,m; 15 int main(){ 16 scanf("%d%d",&n,&m); 17 int i,j; 18 for(i=2;i*i<=m;i++)//分解质因数 19 if(m%i==0){ 20 pri[++cnt]=i; 21 while(m%i==0){ 22 m/=i; 23 t[cnt]++; 24 } 25 } 26 if(m>1)pri[++cnt]=m,t[cnt]++; 27 for(i=1;i<n-1;i++){ 28 int a=n-i,b=i; 29 for(j=1;j<=cnt;j++){ 30 while(a%pri[j]==0){ 31 a/=pri[j]; 32 c[j]++; 33 } 34 } 35 for(j=1;j<=cnt;j++){ 36 while(b%pri[j]==0){ 37 b/=pri[j]; 38 c[j]--; 39 } 40 } 41 flag=0; 42 for(j=1;j<=cnt;j++){ 43 if(c[j]<t[j]){ 44 flag=1;break; 45 } 46 } 47 if(!flag){ans[++num]=i+1;} 48 } 49 printf("%d\n",num); 50 for(i=1;i<=num;i++) 51 printf("%d ",ans[i]); 52 printf("\n"); 53 return 0; 54 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5911162.html