Codeforces1371 E2. Asterism (Hard Version)

Posted live4m

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1371 E2. Asterism (Hard Version)相关的知识,希望对你有一定的参考价值。

题意:

给定长度为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;


以上是关于Codeforces1371 E2. Asterism (Hard Version)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #654 (Div. 2)A-E1

codeforces 391E2 (Codeforces Rockethon 2014E2)

CodeForces - 1251E2 (思维+贪心)

codeforces#1251E2. Voting (Hard Version)(贪心)

CodeForces -Codeforces Round #496 (Div. 3) E2. Median on Segments (General Case Edition)

Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力