Codeforces Round #654 (Div. 2)E. Asterism(思维)⭐⭐⭐⭐

这道题让你求方案数 f ( x ) f(x) f(x)不能被p整除的x.

又是一道思维盲点题:这道题的答案是一个连续的区间。

最小满足条件的x=l很好求,最大的满足条件的也求出的话,答案就出来了。
首先将a从小到大排序,可以发现对于回合i,有 ( x + i − 1 ) (x+i-1) (x+i1)个candy。
该回合可以使得f(x)乘上 ( c n t − i + 1 ) , c n t 为 a 中 小 于 等 于 c a n d y i 的 元 素 个 数 (cnt-i+1),cnt为a中小于等于candy_i的元素个数 (cnti+1),cntacandyi

现在来证明答案为什么是连续的区间:
求出最小的x之后,你每次增加x,都会使得 ( c n t − i + 1 ) (cnt-i+1) (cnti+1)这个函数 f ( x , i ) f(x,i) f(x,i)有几率上移,可知答案的r就是刚好有点出现 ( c n t − i + 1 ) = p (cnt-i+1)=p (cnti+1)=p的情况的x,再减去一。

具体实现代码如下:

#include<bits/stdc++.h>
using namespace std;
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)
#define MAXN 105000
#define ll long long
const ll mod=1000000007;
int a[MAXN];
int n,p;
inline bool read() {

    scanf("%d%d",&n,&p);
    for(int i=1;i<=n;i++)
        scanf("%d",a+i);
    sort(a+1,a+1+n);
}
void solve()
{
    int l=1;
    for(int i=1;i<=n;i++)
        l=max(a[i]+1-i,l);
    int r=a[n]+1;
    for(int i=1;i<=n;i++) {
        if(p+i-1<=n)
        r = min(a[p+i-1] + 1 - i, r);
    }
    if(r==a[n]+1||r<=l)r=l;
    cout<<r-l<<endl;
    for(int i=l;i<r;i++)
        printf("%d%c",i,i==r?'\n':' ');
}
int main() {
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
#endif
    read();
    solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值