CF2157D Billion Players Game

发现最终答案为\(x\times p+y\)的形式,所以当\(a>0\)\(p=l\)取到最小值否则\(p=r\)取到最小值。
考虑先决定满足\(a_i<l||r<a_i\)\(a_i\),设此时答案为\(A\times p+B\)。分类讨论
\(A\le0\)\(p\)\(l\)所以要声称一些\(p-a_i\)直到\(A==0(\)\(a_i\)全部分配完\()\) 发现要取最小的\(-A\)\(a_i\)。剩下的最大和最小匹配,变成\(\begin{array}{lr}\ \ \ \ a_i-p+p-a_j\\=a_i-a_j\end{array}\) 计算答案
\(A>0\)同理
代码

#include<bits/stdc++.h>
using namespace std;
namespace IO{
    template<typename T>
    inline void read(T&x){
        x=0;char c=getchar();bool f=0;
        while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        f?x=-x:0;
    }
    template<typename T>
    inline void write(T x){
        if(x==0){putchar('0');return ;}
        x<0?x=-x,putchar('-'):0;short st[50],top=0;
        while(x) st[++top]=x%10,x/=10;
        while(top) putchar(st[top--]+'0');
    }
    inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
    inline void write(char c){putchar(c);}
    inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
    inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
    template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
    template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
    template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
#define int long long
const int maxn=200010;
int a[maxn];
void solve(){
    int n,l,r,p=0,b=0;read(n,l,r);
    vector<int>vt;
    for(int i=1;i<=n;i++){
        read(a[i]);
        if(a[i]<l) p++,b-=a[i];
        else if(a[i]>r) p--,b+=a[i];
        else vt.push_back(a[i]);
    }
    if(p<0){
        sort(vt.begin(),vt.end(),greater<int>());
        while(!vt.empty()&&p<0) p++,b-=vt.back(),vt.pop_back();
    }
    else{
        sort(vt.begin(),vt.end());
        while(!vt.empty()&&p) p--,b+=vt.back(),vt.pop_back();
    }
    sort(vt.begin(),vt.end());
    for(int i=0;i<vt.size()/2;i++) b+=vt[vt.size()-i-1]-vt[i];
    if(p<0) write(r*p+b);
    else write(l*p+b);
    write('\n');
}
signed main(){
    int T;read(T);
    while(T--) solve();
    return 0;
}
posted @ 2025-11-24 19:17  Link-Cut_Trees  阅读(5)  评论(0)    收藏  举报