irrelevant Elements (組合數學)uva-1635
阿新 • • 發佈:2019-02-11
題目大意:
對於給定的n個數a1,a2,a3....an,一次求出相鄰兩個數之和,將得到一個新的數列。重複上述操作,最後結果將變成一個數。問這個數除以m的餘數與那些數無關?例如n=3,m=2時,第一次求和結果a1+a2,a2+a3,在求和a1+2a2+a3,它除以2的餘數和a2無關,1<=n<=10^5,2<=m<=10^9
題解:(紫書p320)
顯然最後的求和式是a1,a2,a3....an的線性組合。設ai的係數為f(i),則和式除以m的餘數與ai無關,當且僅當f(i)是i的倍數。列如,當n=5時,最後結果為a1+4a2+6a3+4a4+a5
其中係數為1 4 6 4 1,可見是楊輝三角的第5行。那麼通過定理,最後ai的係數是C(i-1,n-1)。這樣問題就變成了C(0,n-1),C(1,n-1)....C(n-1,n-1)中有幾個是m的倍數。
紫書上有一個遞推結論C(k,n)=(n-k+1)/k*C(k-1,n),如果直接去求C(i-1,n-1)會爆long long 。那麼就用唯一分解定理先將m分解了,然後在對C(i-1,n-1)分解了,看他們的素因子的指數是否合理,如果合理就是倍數關係。所謂合理就是C(i-1,n-1)的每一個素因子指數都要大於等於m的素因子指數
#include <bits/stdc++.h> #define N 100005 using namespace std; int prime[N]; int vis[N]; int a[N]; int fec[10000][2]; int fecn[10000]; int fec_num; int pri_num; void putm(int m) { fec_num=0; for(int i=2; i*i<=m; i++) { if(m%i==0) { int num=0; while(m%i==0) { m=m/i; num++; } fec[fec_num][0]=i; fec[fec_num++][1]=num; } // if(m==1)break; } if(m>1) { fec[fec_num][0]=m; fec[fec_num++][1]=1; } } bool cheak(int n,int k) { int x=n-k+1; int y=k; for(int i=0;i<fec_num;i++) { int p=fec[i][0]; int &q=fecn[i]; while(x%p==0) { x=x/p; q++; } while(y%p==0) { y=y/p; q--; } } for(int i=0;i<fec_num;i++) { if(fecn[i]<fec[i][1])return false; } return true; } int main() { int n,m; int cnt; while(cin>>n>>m) { putm(m); cnt=0; memset(fecn,0,sizeof(fecn)); for(int i=1;i<n;i++) { if(cheak(n-1,i)) { a[cnt++]=i+1; } } printf("%d\n",cnt); for(int i=0;i<cnt;i++) { if(i==0)printf("%d",a[i]); else printf(" %d",a[i]); } printf("\n"); } return 0; }