这个程序跑了2s, 用了C(n, k)=C(n, n-k), 把时间缩短了一半, 不然就是TLE啊。
没有想到好的去重方法, 就再转到另一个数组里来去重。
本题的输出保证每组数据有两行, 就是第一行如果是0, 还要输出一行空行, 被这里坑了半天。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define ll long long
#define llu unsigned long long
const int maxn=100000+10;
int n, k;
int e[maxn];
void add_integer(int n, int d)
{
int i=2, t=n;
while(i<=(int)sqrt((double)t)+1)
{
while(t%i==0)
{
e[i]+=d;
t/=i;
}
i++;
}
if(t>1)
e[t]+=d;
}
int main()
{
while(cin>>n>>k)
{
memset(e, 0, sizeof(e));
map<int, int> m;
vector<int> v;
v.clear();
m.clear();
int i=2;
int t=k;
int en=(int)sqrt((double)t);
while(i<=en)
{
while(t%i==0)
{
if(!m.count(i))
{
v.push_back(i);
m[i]=1;
}
else m[i]++;
t/=i;
en=(int)sqrt((double)t);
}
i++;
}
if(t>1)
{
v.push_back(t);
m[t]=1;
}
vector<int> ans;
for(int i=1; i<=(n+1)/2; i++)
{
add_integer(n-i, 1);
add_integer(i, -1);
int ok=1;
for(int j=0; j<v.size(); j++)
if(v[j]>n-1 || e[v[j]]<m[v[j]])
{
ok=0;
break;
}
if(ok)
{
ans.push_back(n-i);
ans.push_back(i+1);
}
}
sort(ans.begin(), ans.end());
vector<int> ans1;
if(!ans.empty())
ans1.push_back(ans[0]);
for(int i=1; i<ans.size(); i++)
if(ans[i]!=ans1[ans1.size()-1])
ans1.push_back(ans[i]);
cout<<ans1.size()<<endl;
if(ans1.size()==0)
cout<<endl;
for(int i=0; i<ans1.size(); i++)
cout<<ans1[i]<<(i==ans1.size()-1?'\n':' ');
}
return 0;
}