问题
分析
求出
C
n
k
,
0
=
<
k
<
=
n
C_n^k,0=<k<=n
Cnk,0=<k<=n的所有,判断那些可以被m整除,然后输出
使用
C
n
k
=
n
−
k
+
1
k
C
n
k
−
1
C_n^k=\frac{n-k+1}{k}C_n^{k-1}
Cnk=kn−k+1Cnk−1递推,因为要对出发的结果取余数,所以不能直接对每个系数依次取余,而且i模m的逆元不一定存在,因为gcd(i,m)不等于1
#include <cstring>
#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=100000+5;
int n,m,bad[maxn],nprime[maxn],p;
vector<int> prime; //m的所有质因子
//分解m的质因数
void prime_factor(){
p=0;
int t=sqrt(m+0.5),t2=m;
for(int i=2;i<=t;++i){
if(t2%i==0){
nprime[p]=1;
prime.push_back(i);
t2/=i;
while(t2%i==0){
t2/=i;
++nprime[p];
}
++p;
}
if(t2==1) return;
}
if(t2>1){
nprime[p]=1;
prime.push_back(t2);
++p;
}
}
int main(void){
while(cin>>n>>m) {
prime.clear();
prime_factor();
memset(bad,0,sizeof(bad));
n--;
//对于m的每一个质因子,C(n,0)-C(n,n)对这种质因子的幂
for(int i=0;i<p;++i){
int a=prime[i],b=nprime[i],temp=0,temp2;
for(int j=1;j<=n;++j){
temp2=n-j+1;
while(temp2%a==0){
temp++;
temp2/=a;
}
temp2=j;
while(temp2%a==0){
temp--;
temp2/=a;
}
if(temp<b) bad[j]=1; //不能除尽m
}
}
vector<int> ans;
for(int i=1;i<=n;++i){
if(bad[i]==0) ans.push_back(i+1); //编号从1开始
}
printf("%d\n",ans.size());
if(!ans.empty()) printf("%d",ans[0]);
for(int i=1;i<ans.size();++i){
printf(" %d",ans[i]);
}
printf("\n");
}
return 0;
}