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
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章