AGC-018-C Coins——题解

AGC-018-C Coins——题解

原题
洛谷

思路

考虑一个贪心的思想,哪个人的某种币多,就对应地取那个人的某种币。但是可能某个人有多种币都很多的情况,那样就很难讨论取舍,这种时候就需要用上反悔了。

第一步,我们先随便选择 $ x $ 个人选金币, $ y $ 个人选银币, $ z $ 个人选铜币,由于我们可以反悔,所以初始的选择状态并不会产生影响。

第二步,我们需要考虑该如何反悔,很容易可以想到改变部分人的选择状态,同时由于固定有 $ x $ 个人选金币, $ y $ 个人选银币, $ z $ 个人选铜币,所以改变状态的某些人必然是形成一个环状的传递链。仔细思考后会发现只有以下五种情况:

  1. $ x->y,y->z,z->x $ ;
  2. $ x->z,y->x,z->y $ ;
  3. $ x->y,y->x $ ;
  4. $ y->z,z->y $ ;
  5. $ x->z,z->x $ 。

最后用用优先队列维护一下 $ 6 $ 种一对一的改变状态即可。

code

#include <bits/stdc++.h> 
#define i8  __int128
#define int long long 
#define fuck inline
#define lb long double 
using namespace std; 
// typedef long long ll; 
const int N=5e5+23,M=5e5+520,mod=536870912;
const int inf=INT_MAX,INF=1e9+7; 
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118; 
// const int M=mod1*mod2;
fuck int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
    return x*f;
}
fuck void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int X,Y,Z;
struct node
{
    int w,id;
    friend bool operator <(node x,node y){return x.w<y.w;} 
};
priority_queue<node>q1,q2,q3,q4,q5,q6;
int a[N],b[N],c[N],vis[N];
fuck void add(int i)
{
    q1.push((node){(b[i]-a[i]),i});//x->y
    q2.push((node){(c[i]-b[i]),i});//y->z
    q3.push((node){(c[i]-a[i]),i});//x->z
    q4.push((node){(a[i]-b[i]),i});//y->x 
    q5.push((node){(b[i]-c[i]),i});//z->y
    q6.push((node){(a[i]-c[i]),i});//z->x
}
int ans=0;
fuck void solve()
{
    cin>>X>>Y>>Z;int n=X+Y+Z;memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)cin>>a[i]>>b[i]>>c[i];
    for(int i=1;i<=X;i++)vis[i]=1,ans+=a[i];
    for(int i=X+1;i<=X+Y;i++)vis[i]=2,ans+=b[i];
    for(int i=X+Y+1;i<=X+Y+Z;i++)vis[i]=3,ans+=c[i];
    for(int i=1;i<=n;i++)add(i);
    while(1)
    {
        while(!q1.empty()&&vis[q1.top().id]!=1)q1.pop();
        while(!q2.empty()&&vis[q2.top().id]!=2)q2.pop();
        while(!q3.empty()&&vis[q3.top().id]!=1)q3.pop();
        while(!q4.empty()&&vis[q4.top().id]!=2)q4.pop();
        while(!q5.empty()&&vis[q5.top().id]!=3)q5.pop();
        while(!q6.empty()&&vis[q6.top().id]!=3)q6.pop();
        //这里由于标记不符合队列要求的数据会被直接踢掉,所以后面暴力地往六个队列丢即可
        int w1=(q1.empty()?-inf:q1.top().w);
        int w2=(q2.empty()?-inf:q2.top().w);
        int w3=(q3.empty()?-inf:q3.top().w);
        int w4=(q4.empty()?-inf:q4.top().w);
        int w5=(q5.empty()?-inf:q5.top().w);
        int w6=(q6.empty()?-inf:q6.top().w);
        int f=0,sum=0;
        if(w1+w2+w6>sum)sum=w1+w2+w6,f=1;//x->y,y->z,z->x
        if(w3+w4+w5>sum)sum=w3+w4+w5,f=2;//x->z,y->x,z->y
        if(w1+w4>sum)sum=w1+w4,f=3;//x->y,y->x
        if(w2+w5>sum)sum=w2+w5,f=4;//y->z,z->y
        if(w3+w6>sum)sum=w3+w6,f=5;//x->z,z->x
        if(sum==0){break;}
        ans+=sum;
        if(f==1)
        {
            int x=q1.top().id,y=q2.top().id,z=q6.top().id;
            vis[x]=2,vis[y]=3,vis[z]=1;
            add(x);add(y);add(z);
        }
        if(f==2)
        {
            int x=q3.top().id,y=q4.top().id,z=q5.top().id;
            vis[x]=3,vis[y]=1,vis[z]=2;
            add(x);add(y);add(z); 
        }
        if(f==3)
        {
            int x=q1.top().id,y=q4.top().id;
            vis[x]=2,vis[y]=1;
            add(x),add(y);
        }
        if(f==4)
        {
            int y=q2.top().id,z=q5.top().id;
            vis[y]=3,vis[z]=2;
            add(y),add(z);
        }
        if(f==5)
        {
            int x=q3.top().id,z=q6.top().id;
            vis[x]=3,vis[z]=1;
            add(x),add(z);
        }
    }
    cout<<ans<<"\n";
}
signed main() 
{ 
    // ios::sync_with_stdio(false); 
    // cin.tie(0); cout.tie(0); 
    // int fuckccf=read();
    // int QwQ=read();
    // while(QwQ--)solve(); 
    solve(); 
    return 0; 
}
//  6666   66666  666666 
// 6    6  6   6      6 
// 6    6  6666      6 
// 6    6  6  6    6 
//  6666   6   6  6666666

完结收工!!!!!

个人主页

看完点赞,养成习惯

\(\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\)

posted @ 2025-06-29 16:28  Nightmares_oi  阅读(23)  评论(0)    收藏  举报