题目链接
题意:
假设你有x颗糖果,你面前有n个敌人,第i个敌人有a[i]颗糖果,你可以选择对战的顺序,如果你手里的糖果不比敌人少,那么你胜利并获得一颗糖果,现在我们定义f(x)为你手里有x颗糖果时,你能打败所有对手的方案数,对于给定质数p,如果f(x)与p互质,那么这个x就是符合要求的,现在给定n,p和a[i],问你有多少个x符合条件,并且输出这些x。
思路:
首先我们要判断x的范围,如果x是>=2000的数,那么所有的敌人他可以随意挑战,f(x)和p肯定不会互质,所以x<=2000,而我们确定了x的范围之后就可以在1~2000之中查找答案,首先我们将a[i]排序,然后二分查找能够挑战的人数,减去x++之前能够挑战的人数,如果x能够成功挑战更多的人,那么x继续++,而且最终的f(x)也会乘上多挑战的人数,最终的f(x)就会乘上能够挑战的人数,所以如果能够挑战的人数%p等于0,即f(x)会乘上一个p的倍数,那么f(x)和p肯定不会互质,直接break,因为p是一个质数,所以我们不需要考虑f(x)的结果(目测如果考虑会爆long long),只需要考虑过程中是否乘有p的倍数即可。
代码:
#include<bits/stdc++.h>
using namespace std
;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N
=2e5+5;
const int mod
=998244353;
const int inf
=0x7fffffff;
const double pi
=3.1415926535;
using namespace std
;
signed main()
{
vector
<int>v
;
int n
,p
,po
,arr
[N
];
cin
>>n
>>p
;
for(int i
=1;i
<=n
;i
++)
{
cin
>>arr
[i
];
}
sort(arr
+1,arr
+n
+1);
for(int i
=1;i
<=2000;i
++)
{
int cnt
=0,res
=0,fg
=1;
for(int j
=1;j
<=n
;j
++)
{
po
=upper_bound(arr
+1,arr
+n
+1,i
+cnt
)-arr
;
po
--;
if((po
-cnt
)%p
==0)
{
fg
=0;
break;
}
cnt
++;
}
if(fg
)
{
v
.push_back(i
);
}
}
cout
<<v
.size()<<endl
;
for(int i
=0;i
<v
.size();i
++)
{
cout
<<v
[i
]<<" ";
}
return 0;
}