cf1091E. New Year and the Acquaintance Estimation

mac2025-08-31  9

链接

点击跳转

题解

我也不是很懂…抄的题解

Erdős–Gallai定理:

降序序列 { d i } \{d_i\} {di}可图的一个充要条件为:

∀ k ∈ [ 1 , n ] , ∑ i = 1 k d i ≤ [ k ( k − 1 ) + ∑ i = 1 n m i n ( d i , k ) ] \forall k \in [1,n], \sum_{i=1}^kd_i \leq \left [ k(k-1) + \sum_{i=1}^n min(d_i,k) \right ] k[1,n],i=1kdi[k(k1)+i=1nmin(di,k)]

然后题解又说满足条件的度数肯定是连续的一段(间隔2),这个也不是很懂

题解还说判断一个度大了还是小了,可以通过不等式不成立的时候 d n + 1 d_{n+1} dn+1在等式的哪边

二分一下好像就可以了

代码

#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define iinf 0x3f3f3f3f #define linf (1ll<<60) #define eps 1e-8 #define maxn 1000010 #define maxe 1000010 #define cl(x) memset(x,0,sizeof(x)) #define rep(_,__) for(_=1;_<=(__);_++) #define em(x) emplace(x) #define emb(x) emplace_back(x) #define emf(x) emplace_front(x) #define fi first #define se second #define de(x) cerr<<#x<<" = "<<x<<endl using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; ll read(ll x=0) { ll c, f(1); for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f; for(;isdigit(c);c=getchar())x=x*10+c-0x30; return f*x; } ll pre[maxn], suf[maxn], n, d[maxn], tmp[maxn]; #define too_big -1 #define too_small 1 #define ok 0 ll check(ll v) { ll i, p, k, pos, s=0; rep(i,n)tmp[i]=d[i]; tmp[n+1]=v; sort(tmp+1,tmp+n+2,greater<ll>()); rep(i,n+1)pre[i]=pre[i-1]+tmp[i]; for(i=1;tmp[i]!=v;i++);pos=i; p=n+1; for(k=1;k<=n+1;k++) { while(p>k and tmp[p]<k)s+=tmp[p--]; while(p<k)s-=tmp[++p]; if(pre[k]>k*(k-1)+s+(p-k)*k) { if(k>=pos)return too_big; else return too_small; } } return ok; } int main() { ll i, L, R, l, r, mid, t=0; n=read(); rep(i,n)d[i]=read(), t+=d[i]; t=t&1; l=0, r=n/2; while(l<r) { mid=l+r>>1; if(check(2*mid+t)==too_small)l=mid+1; else r=mid; } L=l; l=0, r=n/2; while(l<r) { mid=l+r+1>>1; if(check(2*mid+t)==too_big)r=mid-1; else l=mid; } R=l; if(check(2*L+t)==ok) { for(i=L;i<=R;i++)printf("%lld ",2*i+t); } else { printf("-1"); } return 0; }
最新回复(0)