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;
}

 

posted @ 2023-10-03 09:32  JMXZ  阅读(15)  评论(0)    收藏  举报