Codeforces Round #623 D. Recommendations(并查集维护)

题目链接

参考题解

D. Recommendations

题意:输入n  第一行输入n个种类书的数量num,第二行输入每个种类想要生产一本书的消耗t,现在要求你增加某些种类的书,使得n个种类的书的数量都不一样

题解:瞎贪心半天 不是超时就是 wa  搜了一波题解。很明显t最大的不变,操作t小的,t越小的,往后+1的操作越多。优先考虑时间大的在前面 排序,然后  并查集 维护当前num 能到达最远的数。做法很妙的一个题吧。由于时间大的在前面,所以每次扫的时候就会自然的把时间大的给跳过了 第二大的最会跳到最近的一个,以此类推

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=2e5+10;
int n;
struct node
{
    int num;
    ll t;
    bool operator <(const node &o)const
    {
        if(o.t==t) return o.num>num;
        return o.t<t;
    }
}a[N];
map<int,int>fa;
int fin(int x)
{
    if(fa[x]==0) return x;
    return fa[x]=fin(fa[x]);
    //return fa[x];
}
int mix(int x,int y)
{
    int fx=fin(x);
    int fy=fin(y);
    //printf("x:%d fx:%d y:%d fy:%d\n",x,fx,y,fy);
    if(fx!=fy) fa[fx]=fy;
}
int main()
{
    scanf("%d",&n);
    rep(i,1,n) scanf("%lld",&a[i].num);
    rep(i,1,n) scanf("%lld",&a[i].t);
    sort(a+1,a+1+n);
    ll ans=0;
    rep(i,1,n)
    {
        int res=fin(a[i].num);
        //printf("num:%d res:%d\n",a[i].num,res);
        if(res==a[i].num){
            mix(res,res+1);
        }
        else{
            mix(res,res+1);
            ans+=1ll*(res-a[i].num)*a[i].t;
        }
    }
    printf("%lld\n",ans);
}
/*
5
1 1 1 1 1
1 1 1 1 1
*/
发布了498 篇原创文章 · 获赞 66 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/104481555