Pagini recente » Cod sursa (job #3134076) | Cod sursa (job #2954631) | Cod sursa (job #696098) | Cod sursa (job #1386184) | Cod sursa (job #393591)
Cod sursa(job #393591)
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#define PB push_back
#define GM 75005
#define NM 20005
#define inf 30000
int N,G,gmax;
short int P[GM],D[GM],E[GM];
int CATE[205];
short int B[GM][16],R[GM][16][2],A[GM][2];
int IND[1005],ob[NM];
vector<int> V;
inline void PD(int cat)
{
for(int j=0;j<cat;++j)
{
int st=0,dr=-1;
for(int k=0;k*cat+j<=G;++k)
{
while((st<=dr) && (k*cat+j-IND[st])>CATE[cat]*cat) ++st;
int val_cur=P[k*cat+j];
if(val_cur!=inf)
{
while((st<=dr) && (val_cur<=P[IND[dr]]+(k*cat+j-IND[dr])/cat)) --dr;
++dr;
IND[dr]=k*cat+j;
}
if(st<=dr)
{
D[k*cat+j]=P[IND[st]]+(k*cat+j-IND[st])/cat;
E[k*cat+j]=(k*cat+j-IND[st])/cat;
}
else D[k*cat+j]=inf;
}
}
}
int main()
{
int g;
freopen("ghiozdan.in","r",stdin);
freopen("ghiozdan.out","w",stdout);
scanf("%d %d",&N,&G);
for(int i=1;i<=N;++i)
{
scanf("%d",&g);
gmax=max(gmax,g);
if(!CATE[g]) V.PB(g);
++CATE[g];
}
N=V.size();
int sq=(int)sqrt(N);
V.PB(0);
sort(V.begin(),V.end());
int dim=0;
for(int i=1;i<=G;++i)
{
A[i][0]=inf;
B[i][0]=inf;
}
for(int i=1;i<=N;++i)
{
int cur=i%2;
int prev=!cur;
int cat=V[i];
for(int j=0;j<=G;++j)
A[j][cur]=inf;
for(int j=0;j<cat;++j)
{
int st=0,dr=-1;
for(int k=0;k*cat+j<=G;++k)
{
//scoateri
while((st<=dr) && (k*cat+j-IND[st])>CATE[cat]*cat) ++st;
//inserari
int val_cur=A[k*cat+j][prev];
if(val_cur!=inf)
{
while((st<=dr) && (val_cur<=A[IND[dr]][prev]+(k*cat+j-IND[dr])/cat)) --dr;
++dr;
IND[dr]=k*cat+j;
}
if(st<=dr) A[k*cat+j][cur]=A[IND[st]][prev]+(k*cat+j-IND[st])/cat;
else A[k*cat+j][cur]=inf;
}
}
if(i%sq==0)
{
++dim;
for(int j=0;j<=G;++j) B[j][dim]=A[j][cur];
}
}
int ind=G;
while(A[ind][N%2]==inf) --ind;
int ans=A[ind][N%2];
printf("%d %d\n",ind,ans);
int poz=ind;
if(N%sq==0) --dim;
int indi=N;
int d=0;
for(int l=dim;l>=0;--l)
{
for(int j=0;j<=G;++j)
R[j][0][0]=B[j][l];
for(int i=l*sq+1,ii=1;i<=min((l+1)*sq,N);++i,++ii)
{
for(int j=0;j<=G;++j)
P[j]=R[j][ii-1][0];
PD(V[i]);
for(int j=0;j<=G;++j)
{
R[j][ii][0]=D[j];
R[j][ii][1]=E[j];
}
}
int indii=indi%sq;
if(indii==0) indii=sq;
while(indii)
{
for(int j=1;j<=R[poz][indii][1];++j)
ob[++d]=V[indi];
poz-=(R[poz][indii][1]*V[indi]);
--indi;
--indii;
}
}
// sort(ob+1,ob+d+1);
int sum=0;
for(int i=1;i<=d;++i)
{
printf("%d\n",ob[i]);
sum+=ob[i];
}
//printf("%d %d",sum,d);
return 0;
}