CF1832D2 Red-Blue Operations
/* 最小值最大-> 二分 -> 右偏 r=mid-1 l<r 首先考虑最简单情况 sort(a) k<=n 则倒叙 加上 ai 若人不符合 return0 k>n >>因为1~k 所以连续两次操作 -1 >>ai'=ai+p1-p2+p3-p4....(-1)^(t-1)pt 操作奇数次 一定增 偶数次一定减 尽可能操作奇数次 且 pi-pi+1 ==-1 尽可能的小 >>不可能 两个数都操作偶数次 否则可以移动 使ai aj 都 ++ 1.k mod2 == n mod2 每个数都可以操作 0/奇数次 ->不减 2.-------!=------ 一定有一个数操作了偶数次 >>可以倒序操作 n===k mod 不影响 n!==k mod 操作偶数次的数 反正都要 -1 * k sort(a)->对于每一次询问的 k -> 1.ai+=k-i+1 ->若仍然有 ai < x return 0(之后更不可能) ->pre_mn 对于所有 < x 的数 记 cnt(0-n) 个: ->lower_bound 特判:cnt==0 (n==1&&k%2==0)return a[1]-k/2>=x else return 1 2. k<=n return 1 3. k-cnt%2===1 return n>cnt 4. k-cnt%2!=1 && (n-cnt)>=2 return 1 5. else return pre_b+cnt*k+sum[n]-sum[cnt]-n*x (s==b1~bcnt + cnt*k- cnt*x) (k-cnt%2==0&&n-cnt<=1||) (n==cnt/cnt+1 && k==cnt) ->pre_b sum(a) */ #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> //#include<queue> //#include<vector> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------------\n"); using namespace std; const int maxn=2e5+10 ; const int mod=998244353; const int inf=0x3f3f3f3f; ll n,q,k; ll a[maxn],b[maxn],pre_mn[maxn],pre_b[maxn],sum[maxn]; ll ok(ll x) { int cnt=lower_bound(a+1,a+1+n,x)-a-1; if(cnt==0){ if(n==1&&k%2==0) return a[1]-k/2>=x; return 1; } if(pre_mn[cnt]+k<x) return 0; if(k<=n) return 1; if((k-cnt)%2==1) return n>cnt; if(n-cnt>=2) return 1;//与奇偶无关 else { ll tmp = pre_b[cnt] + k * cnt + sum[n] - sum[cnt] - n * x; return 2*tmp >= (k - cnt); } } int main() { ios::sync_with_stdio(false); memset(pre_mn,inf,sizeof(pre_mn)); cin>>n>>q; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i],b[i]=a[i]+1-i,pre_b[i]=pre_b[i-1]+b[i],pre_mn[i]=min(pre_mn[i-1],b[i]); for(int i=1;i<=q;i++){ cin>>k; ll l=-1e18,r=1e18; while(l<r) { ll mid=(l+r+1)>>1; if(ok(mid)) l=mid; else r=mid-1; } cout<<l<<'\n'; } return 0; }