题意:
给定n个数a1,a2,a3.....an,依次求出相邻的两个数的和,最后成为一个数,问这个数模m的值与那些最初的数无关
例:a1,a2,a3, m=2 => a1+a2,a2+a3 => a1+2a2+a3 ,显然第二项无关。
代码:
//可以看出最后得到的式子符合杨辉三角,所以可以递推出所有的项的系数(c(i+1)=c(i)*(n-i)/(i+1)), //但是数太大不能直接计算,可以将他们分解成 a1^p1*a2^p2*... 的形式,这样就只需要判断因子的指数的大小即可。 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=100000; int c[maxn+10]; int ans[maxn+10],prime[maxn+10],re[maxn+10],tot; void init(int m,int p){ tot=0; memset(re,0,sizeof(re)); for(int i=2;i<=sqrt(m+0.5);i++){ if(m%i==0){ prime[++tot]=i; while(m%i==0){ m/=i; re[tot]+=p; } } } if(m>1){ prime[++tot]=m; re[tot]+=p; } } int solve(int m,int p){ for(int i=2;i<=sqrt(m+0.5);i++){ if(m%i==0){ while(m%i==0){ m/=i; c[i]+=p; } } } if(m>1) c[m]+=p; for(int i=1;i<=tot;i++){ if(prime[i]>maxn) return 0; else if(c[prime[i]]<re[i]) return 0; } return 1; } int main() { int n,m; while(scanf("%d%d",&n,&m)==2){ init(m,1); int cnt=0; memset(c,0,sizeof(c)); n--; for(int i=0;i<n;i++){ solve(n-i,1); int tmp=solve(i+1,-1); if(tmp) ans[++cnt]=i+2; } printf("%d ",cnt); for(int i=1;i<=cnt;i++) printf("%d%c",ans[i],i==cnt?' ':' '); if(cnt==0) printf(" ");//坑!!! } return 0; }