Pagini recente » Cod sursa (job #2088880) | Cod sursa (job #1109189) | Cod sursa (job #2348812) | Cod sursa (job #800046) | Cod sursa (job #393635)
Cod sursa(job #393635)
#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
#define maxbuf 65536
FILE*fin=fopen("ghiozdan.in","r");
int N,G;
int P[GM],D[GM],E[GM];
int B[GM][15],R1[GM][15],R2[GM][15],A[GM][2],CATE[205];
char buf[maxbuf];
int u;
inline void refbuf()
{
int ans=fread(buf,1,maxbuf,fin);
if(ans<maxbuf) buf[ans]=0;
u=0;
}
inline int nr()
{
int ans=0;
one:
while(u<maxbuf && !isdigit(buf[u])) ++u;
if(u==maxbuf)
{
refbuf();
goto one;
}
two:
while(u<maxbuf && isdigit(buf[u]))
{
ans=ans*10+buf[u]-'0';
++u;
}
if(u==maxbuf)
{
refbuf();
goto two;
}
return ans;
}
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);
refbuf();
N=nr();
G=nr();
for(int i=1;i<=N;++i)
{
g=nr();
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]];
sum=min(sum,G);
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)
R1[j][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]=R1[j][ii-1];
PD(V[i],G);
for(int j=0;j<=G;++j)
{
R1[j][ii]=D[j];
R2[j][ii]=E[j];
}
}
int indii=indi%sq;
if(indii==0) indii=sq;
while(indii)
{
for(int j=1;j<=R2[poz][indii];++j)
printf("%d\n",V[indi]);
poz-=(R2[poz][indii]*V[indi]);
--indi;
--indii;
}
}
return 0;
}