题意:
给定长度为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;
}