题解 CF1371E1 【Asterism (Easy Version)】

huayucaiji

2020-07-05 12:02:46

Solution

首先我们可以确定是一个 $O(n^2)$ 的算法。而且我们知道为了赢得所有的对战,~~易得~~$x_{min}=\max(a_i)-n+1$。此时 $\max(a_i)$ 放在最后一个位置。我们分三个情况讨论: 1.$x<\max(a_i)-n+1$,此时无解,即 $f(x)=0$,$p\mid f(x)$,所以不是我们想要的解。 2.$x>\max(a_i)$,此时任意排列都可以,即 $f(x)=n!$,因为 $p\leq n$,$p\mid f(x)$,所以不是我们想要的解。 3.$max(a_i)-n+1\leq x\leq\max(a_i)$,此时有可能有解。 因此我们只需要考虑第三种情况。由于时间充裕,我们可以枚举 $x$,用 $O(n)$ 的时间来计算 $f(x)$。 我们采取计算每一位上有多少个可以放的怪兽,因为可以放在 $i$ 上的怪兽一定可以放在 $i+1$ 的位置上,满足单调性,所以可以从前往后扫。我们记 $t_i$ 为糖果数量小于等于 $i$ 的怪兽的数量。我们可以用排列组合得出下面的式子: $$f(x)=\prod\limits_{i=x}^{x+n-1} t_i-(i-x)$$ $i-x$ 就表示已经用过多少怪兽,剩下 $t_i-(i-x)$ 个可以放。 ```cpp #include<bits/stdc++.h> #define int long long using namespace std; int read() { char ch=getchar(); int f=1,x=0; while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return f*x; } const int maxn=2e4+10; int n,a[maxn],p,t[maxn<<1]; vector<int> ans; signed main() { n=read();p=read(); for(int i=1;i<=n;i++) { a[i]=read(); t[a[i]]++; } sort(a+1,a+n+1); for(int i=1;i<=a[n]+n;i++) { t[i]=t[i]+t[i-1]; } int k=max(0LL,a[n]-n+1); for(int x=k;x<=a[n];x++) { bool flag=1; for(int i=x;i<x+n-1;i++) { if((t[i]-(i-x))%p==0) { flag=0; break; } } if(flag) { ans.push_back(x); } } cout<<ans.size()<<endl; int sz=ans.size(); for(int i=0;i<sz;i++) { cout<<ans[i]<<" "; } return 0; } ```