Cod sursa(job #585988)

Utilizator eudanipEugenie Daniel Posdarascu eudanip Data 30 aprilie 2011 13:04:24
Problema Fabrica Scor 34
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 2.29 kb
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;

#define ll long long
#define NMAX 100015
#define minim(a,b) (a<b ? a : b)

priority_queue<int> heap;
ll A[NMAX/2],va[NMAX/2];
ll ok[NMAX/2],vb[NMAX/2];
ll ta[NMAX],n,a,b,sol;

class cmp
{
public:
    bool operator()(const int& a,const int& b)
    {
        return ok[a]<ok[b];
    }
};
priority_queue<int,vector<int>,cmp> heap2;

void update(int n,int st,int dr,int poz)
{
    if(st==dr)
    {
        A[n]+=va[poz];
        return ;
    }
    int mij=(st+dr)/2;
    if(poz<=mij)
        update(2*n,st,mij,poz);
    else
        update(2*n+1,mij+1,dr,poz);
    A[n]=minim(A[2*n],A[2*n+1]);
}

void change(int n,int st,int dr,int val)
{
    if(st==dr)
    {
        A[n]+=va[st];
        return ;
    }
    int mij=(st+dr)/2;
    if(A[2*n]==val)
        change(2*n,st,mij,val);
    else
        change(2*n+1,mij+1,dr,val);
    A[n]=minim(A[2*n],A[2*n+1]);
}

int merge(int smax)
{
    ll i,last,p;
    last=1;
    for(i=1;i<=b;i++)
        ok[i]=smax-vb[i];
    while(!heap.empty())
        heap.pop();
    while(!heap2.empty())
        heap2.pop();
    for(i=n;i>=1;i--)
    {
        while(last<=b && ta[i]+vb[last]<=smax)
        {
            heap.push(last);
            last++;
        }
        while(1)
        {
            if(heap2.empty())
                break;
            p=heap2.top();
            if(ok[p]<ta[i])
                break;
            heap.push(heap2.top());
            heap2.pop();
        }
        if(heap.empty())
            return 0;
        p=heap.top();
        heap.pop();
        ok[p]-=vb[p];
        heap2.push(p);
    }
    return 1;
}

int main ()
{
    int i;
    ll val;
    
    freopen("fabrica.in","r",stdin);
    freopen("fabrica.out","w",stdout);
    scanf("%lld%lld%lld",&n,&a,&b);
    for(i=1;i<=a;i++)
    {
        scanf("%lld",&va[i]);
        update(1,1,a,i);
    }
    for(i=1;i<=b;i++)
        scanf("%lld",&vb[i]);
    sort(vb+1,vb+b+1);
    for(i=1;i<=n;i++)
    {
        ta[i]=A[1];
        change(1,1,a,ta[i]);
    }
    sol=ta[n];
    
    for(val=(n*vb[b])/2;val>0;val/=2)
        if(!merge(sol+val))
            sol+=val;
    printf("%lld %lld\n",ta[n],sol+1);
    return 0;
}