Pagini recente » Cod sursa (job #14560) | Cod sursa (job #1373206) | Cod sursa (job #1799600) | Cod sursa (job #858210) | Cod sursa (job #393617)
Cod sursa(job #393617)
#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 2000000000
int N,G,gmax;
int P[GM],D[GM],E[GM];
int CATE[205];
int B[GM][16],R[GM][16][2],A[GM][2];
inline void PD(int cat,int pu)
{
int IND[1005];
for(int j=0;j<cat;++j)
{
int st=0,dr=-1;
for(int k=0;;++k)
{
int cp=k*cat+j;
if(cp>pu) break;
while((st<=dr) && (cp-IND[st])>CATE[cat]*cat) ++st;
int vc=P[cp];
if(vc!=inf)
{
while((st<=dr) && (vc<=P[IND[dr]]+(cp-IND[dr])/cat)) --dr;
++dr;
IND[dr]=cp;
}
if(st<=dr)
{
D[cp]=P[IND[st]]+(cp-IND[st])/cat;
E[cp]=(cp-IND[st])/cat;
}
else D[cp]=inf;
}
}
}
int main()
{
int g;
vector<int> V;
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;
A[i][1]=inf;
B[i][0]=inf;
}
int sum=0;
for(int i=1;i<=N;++i)
{
sum+=V[i]*CATE[V[i]];
int cur=i%2;
int prev=!cur;
for(int j=0;j<=sum;++j)
P[j]=A[j][prev];
PD(V[i],sum);
for(int j=0;j<=sum;++j)
A[j][cur]=D[j];
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;
int indi=N;
if(N%sq==0) --dim;
for(int l=dim;l>=0;--l)
{
for(int j=0;j<=G;++j)
R[j][0][0]=B[j][l];
int lim=min((l+1)*sq,N);
for(int i=l*sq+1,ii=1;i<=lim;++i,++ii)
{
for(int j=0;j<=G;++j)
P[j]=R[j][ii-1][0];
PD(V[i],G);
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)
printf("%d\n",V[indi]);
poz-=(R[poz][indii][1]*V[indi]);
--indi;
--indii;
}
}
return 0;
}