题意:
给定长度为n的数组a,表示有n个敌人,第i个敌人有a(i)颗糖
定义f(x)为:
一开始你有x颗糖,对于长度为n的所有排列,都按照排列的顺序去打怪物
当你的糖数量>=怪物的糖数量,那么可以打败怪物,且打败之后你的糖数量+1
f(x)的值就是满足条件的排列数
现在给定一个质数p,要求你找出所有的x,满足f(x)不是p的倍数
保证满足条件的x的数量不超过1e5
数据范围:n<=1e5,1<=a(i)<=1e9
解法:
因为考虑所有排列,所以可以将a数组排序,位置改变不影响最后答案
将a数组从小到大排序,那么对于每个a(i),x不能小于a[i]-(i-1),最所有的下界x取max就是整体下界L
同时每次能赢过的人的数量不能大于等于p,否则最后一定是p的倍数
那么对于每个a(i),x不能大于等于a(i+p-1)-(i-1),对a(i+p-1)-(i-1)-1取min就是整体上界R
如果L<=R,输出[L,R]之间的数即可
否则无解,输出0
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
int a[maxm];
int n,p;
signed main(){
cin>>n>>p;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
int l=1,r=1e9;
for(int i=1;i<=n;i++){
l=max(l,a[i]-(i-1));
}
for(int i=1;i<=n&&i+p-1<=n;i++){
r=min(r,a[i+p-1]-(i-1)-1);
}
if(l<=r){
cout<<r-l+1<<endl;
for(int i=l;i<=r;i++){
cout<<i<<' ';
}
}else{
cout<<0<<endl;
}
return 0;
}