训练作息:
第一周,基本是 8:00-11:00 , 14:00 - 18:00 , 19:00 - 22:00
训练内容:
主要就是训练了5场比赛,4场cf,一场牛客
推荐题目:
E2. Asterism (Hard Version)
题目地址:https://codeforces.com/contest/1371/problem/E2
这题可以去看题解,我也是看官方题解写出来的https://codeforces.com/blog/entry/79624
首先要明白这个式子
其中bi表示的是整个序列中小于等于i的数的个数
当我们选第一个数时,肯定是要选小于等于x的数,即bx
第二个数,肯定要小于等于x+1,即bx+1,但是之前选走了一个数,所以只有bx+1 - 1种
以此类推,可得上式
设max为整个序列的最大值
当
x
+
n
−
1
<
m
a
x
x+n-1<max
x+n−1<max时,携带的最大的都没有序列的最大值大,肯定不行,即f(x)=0 ,不满足
当
x
≥
m
a
x
x\geq max
x≥max时,随便怎么选都可以,即f(x)=n!,也不满足
其他情况就是
m
a
x
−
n
+
1
≤
x
<
m
a
x
max-n+1 \leq x<max
max−n+1≤x<max
我们只需要满足
范围不超过2e5,所以我们可以直接记录i-bi的值,然后直接map找即可
int n,m;
char str[N];
int f[N];
unordered_map<int,int> mm;
int main()
{
rr(n,m);
FOR(i,1,n){
r(f[i]);
}
sort(f+1,f+n+1);
FOR(i,f[n]-n+1,f[n]+n-2){
mm[i]=(i%m-(upper_bound(f+1,f+n+1,i)-f-1)%m+m)%m;
}
unordered_map<int,int> mmm;
int st=max(0,f[n]-n+1);
FOR(i,1,n-1){
int now=st+i-1;
mmm[mm[now]]++;
}
vector<int> ans;
FOR(i,st,f[n]-1){
mmm[mm[i+n-1]]++;
if(mmm.count(i%m)&&mmm[i%m]>0){
// cout<<i<<endl;
}
else{
ans.pb(i);
}
mmm[mm[i]]--;
}
cout<<ans.size()<<endl;
for(int x:ans){
cout<<x<<' ';
}
cout<<endl;
return 0;
}