51nod - 1163 Ingenious union and search O(1) maintenance interval

There are N tasks, each task has a latest end time and a corresponding reward. Complete the task before the end time to get the corresponding reward. The time required to complete each task is 1 unit of time. Sometimes it's impossible to complete all the tasks because there may be a conflict in time, which requires you to make trade-offs. Find the highest reward you can get.

I never thought that union search can be used like
this. Obviously, what needs to be done in this question is to greedy to occupy the big ones first, and then to stuff the small ones as much as possible.
So how to stuff them should also be greedy and start from the end point. If it doesn't work, just push it forward. If this chain reaction process is implemented by union search, it can achieve a speed close to O(1). The
trick is that when x and p[x] are the same, return x-1, indicating that x can occupy , and maintain the relationship

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iin(a) scanf("%d",&a)
#define lin(a) scanf("%lld",&a)
#define din(a) scanf("%lf",&a)
#define s0(a) scanf("%s",a)
#define s1(a) scanf("%s",a+1)
#define print(a) printf("%lld",(ll)a)
#define enter putchar('\n')
#define blank putchar(' ')
#define println(a) printf("%lld\n",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int MAXN = 1e5+11;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
typedef long long ll;
const ll MOD = 1e9+7; 
ll read(){
    ll x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,p[MAXN];
int find(int x){
    if(x==-1) return x;
    if(p[x]==x) return p[x]=x-1;
    return p[x]=find(p[x]);
}
struct P{
    ll ed,cost;
}a[MAXN];
bool cmp(P a,P b){
    return a.cost>b.cost;
}
int main(){
    while(cin>>n){
        rep(i,1,n) p[i]=i;
        rep(i,1,n){
            a[i].ed=min((ll)n,read());
            a[i].cost=read();
        }
        sort(a+1,a+1+n,cmp);
        ll ans=0;
        rep(i,1,n) if(~find(a[i].ed)){
            ans+=a[i].cost;
        }
        println(ans);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324854707&siteId=291194637