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

    技术2022-07-13  78

    这道题让你求方案数 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; }
    Processed: 0.015, SQL: 9