Cod sursa(job #344839)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 31 august 2009 19:17:58
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.72 kb
#include <cstdio>
#include <algorithm>
#include <deque>
using namespace std;
const int VMAX=202;
const int GMAX=75001;
const int Inf=0x3f3f3f3f;
int N,G,cnt[VMAX],din[2][GMAX],Vmax,up[2][GMAX];
deque< pair<int,int> > Q;
void solve(int l,int r,int G)
{
     int i,j,k,m=(l+r)/2,prev=0,now=1;
     if (l==r)
     {
        for (i=1;i<=cnt[l] && G>=l;++i,G-=l)
            printf("%d\n",l);
        return;
     }
     for (i=0;i<=G;++i) din[now][i]=Inf;
     for (i=0;i<=G && i<=cnt[l]*l;i+=l) 
       din[now][i]=i/l,up[now][i]=i;
     for (i=l+1;i<=r;++i)
     {
         now^=1;prev^=1;
         for (j=0;j<i;++j)
             for (Q.clear(),k=j;k<=G;k+=i)
             {
                 int x=din[prev][k] - (k-j)/i;
                 if (din[prev][k] == Inf) x=Inf;
                 while (!Q.empty() && Q.back().first > x) 
                   Q.pop_back();
                 if (!Q.empty() && (k-Q.front().second)/i  > cnt[i])
                   Q.pop_front();
                 Q.push_back(make_pair(x,k));
                 din[now][k]=Q.front().first + (k-j)/i;
                 if (Q.front().first == Inf) din[now][k]=Inf;
                 if (i<=m) up[now][k]=k;
                 else up[now][k]=up[prev][Q.front().second];
             }
     }
     
     for (i=G;din[now][i] == Inf;--i);
     if (l==1 && r==Vmax) printf("%d %d\n",i,din[now][i]);
     i=up[now][i];
     solve(l,m,i);
     solve(m+1,r,G-i);
}
     
int main()
{
    int i,j;
    freopen("ghiozdan.in","r",stdin);
    freopen("ghiozdan.out","w",stdout);
    scanf("%d %d",&N,&G);
    for (i=1;i<=N;++i)
    {
        scanf("%d",&j);
        cnt[j]++;
        Vmax=max(Vmax,j);
    }
    solve(1,Vmax,G);
    return 0;
}