[Explanations] NOI2017 vegetables (greedy)

[Explanations] NOI2017 vegetables (greedy)

Consider this fact:

If you sell a lot of vegetables in a very long time, but only \ (p \) day you sell food. So in fact, you (p \) \ can also perform the same operation days.

This is because

  1. Income food does not change with time
  2. The difference between the volume of the dish does not exist

Title disappear daily fixed \ (x_i \) limit for each vegetable vegetables can be seen as a time to disappear, only to disappear every day \ (m \) vegetables, then we sell the first time after the disappearance of vegetables by. The question then becomes simple. Now it is given a \ (the p-\) , seeking the biggest \ (j \ le p \) so that \ (j \) as well as capacity, is disjoint-set.

Click here to check and analyze the complexity of the set (compression path), the number of times the query set \ (Q \) , complexity \ (O (m * Q + 1E5) \) . (As a point of access will only be m times)

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;  typedef long long ll;
inline int qr(){
    int ret=0,f=0,c=getchar();
    while(!isdigit(c)) f|=c==45,c=getchar();
    while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    return f?-ret:ret;
}

const int maxn=1e6+5;
int n,m,k;
int a[maxn],s[maxn],c[maxn],x[maxn],r[maxn],sav[maxn],cnt;
ll ans[maxn];
int Find(int x){return x==r[x]?x:r[x]=Find(r[x]);}
priority_queue< pair<int,int> > q;

int main(){
    n=qr(),m=qr(),k=qr();
    for(int t=1;t<=n;++t)
        a[t]=qr(),s[t]=qr(),c[t]=qr(),x[t]=qr(),q.push((pair<int,int>){a[t]+s[t],t});   
    for(int t=1;t<=1e5;++t) r[t]=t,sav[t]=m;
    while(q.size()){
        pair<int,int> now=q.top(); q.pop();
        int tar=0;
        if(x[now.second]) tar=Find(min(100000,(c[now.second]-1)/x[now.second]+1));
        else tar=Find(100000);
        if(!tar) continue;
        --c[now.second]; ans[cnt+1]=ans[cnt]+now.first; ++cnt; --sav[tar];
        if(!sav[tar]) r[Find(tar)]=Find(tar-1);
        if(c[now.second]) q.push((pair<int,int>){a[now.second],now.second});
    }
    while(k--) cout<<ans[min(cnt,m*qr())]<<endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/winlere/p/12320674.html