题意: 求 中能整除m的数的序号.
思路: 由于n < 10^5, 所以, 可以利用筛选出10^5以内的素数, 然后唯一分解定理, 求得中各个素因子的指数, 然后与m的指数相比即可. 在分解 时可以只计算m有的素因子, 可以大大降低计算量.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int vis[maxn], p[maxn], cnt = 0, x;
int e[maxn], em[maxn], ans[maxn], c[200];
void init() {
int m = sqrt(maxn + 0.5);
memset(vis, 0, sizeof vis);
for(int i = 2; i <= m; i++) {
if(!vis[i]) {
for(int j = i * i; j < maxn; j += i) vis[j] = 1;
}
}
for(int i = 2; i < maxn; i++) {
if(!vis[i]) p[cnt++] = i;
}
}
void add1(int n, int d) {
for(int i = 0; i < x; i++) {
while(n % c[i] == 0) {
n /= c[i];
e[i] += d;
}
if(n == 1) break;
}
}
bool ok() {
for(int i = 0; i < x; i++) {
if(e[i] < em[i]) return 0;
}
return 1;
}
int main() {
init();
int m, n;
while(~scanf("%d %d", &n, &m)) {
memset(e, 0, sizeof e);
memset(em, 0, sizeof em);
x = 0;
for(int i = 0; i < cnt; i++) {
if(m % p[i] == 0) {
while(m % p[i] == 0) {
m /= p[i];
em[x]++;
}
c[x++] = p[i];
}
if(m == 1) break;
}
if(m > 1) {
printf("0\n\n");
continue;
}
// printf("%d\n", x);
// for(int i = 0; i < x; i++) {
// printf("%d ", c[i]);
// }
n--;
int y = 0;
for(int i = 1; i <= n; i++) {
add1(n - i + 1, 1);
add1(i, -1);
if(ok()) ans[y++] = i + 1;
}
printf("%d\n", y);
for(int i = 0; i < y; i++) {
printf("%d%c", ans[i], i == y - 1 ? '\n' : ' ');
}
if(y == 0) {
printf("\n");
}
}
return 0;
}