Pagini recente » Cod sursa (job #1673539) | Cod sursa (job #1441440) | Cod sursa (job #224020) | Cod sursa (job #2794495) | Cod sursa (job #18833)
Cod sursa(job #18833)
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sz size()
#define Gmax 75005
#define Nmax 20005
int v[201], n, g;
int best[21][Gmax];
int ret[11][Gmax];
int cap, coada, sol;
pair<int, int> Q[Gmax];
vector<int> rez;
void readdata()
{
freopen("ghiozdan.in", "r", stdin);
freopen("ghiozdan.out", "w", stdout);
int i, val;
scanf("%d %d", &n, &g);
for (i = 1; i <= n; ++i)
{
scanf("%d", &val);
v[val]++;
}
}
void rezolva(int K)
{
int poz = K/20, i, j, k, stp = 0;
for (i = 0; i <= g; ++i)
best[0][i] = ret[poz][i];
for (j = K; j < K+20; ++j, ++stp)
{
for (i = 0; i < j; ++i)
{
cap = 1;
coada = 0;
for (k = i; k <= g; k += j)
{
if (coada >= cap)
while (Q[coada].x + (k-Q[coada].y)/j > best[stp][k])
{
--coada;
if (coada < cap) break;
}
Q[++coada] = mp( best[stp][k], k);
if ((k-Q[cap].y)/j > v[j]) ++cap;
best[stp+1][k] = Q[cap].x + (k-Q[cap].y)/j;
}
}
}
for (i = 0; i <= g; ++i)
ret[poz+1][i] = best[20][i];
}
void recon(int K)
{
int poz = K/20, i, j, k, stp = 0;
for (i = 0; i <= g; ++i)
best[0][i] = ret[poz][i];
for (j = K; j < K+20; ++j, ++stp)
{
for (i = 0; i < j; ++i)
{
cap = 1;
coada = 0;
for (k = i; k <= g; k += j)
{
while (coada >= cap && Q[coada].x + (k-Q[coada].y)/j > best[stp][k]) --coada;
Q[++coada] = mp( best[stp][k], k);
if ((k-Q[cap].y)/j > v[j]) ++cap;
best[stp+1][k] = Q[cap].x + (k-Q[cap].y)/j;
}
}
}
stp = 20;
for (j = K+19; j >= K; --j, --stp)
{
for (i = sol; i >= 0; i-= j)
if (best[stp-1][i] + (sol-i)/j == best[stp][sol])
{
for (k = i; k < sol; k += j)
rez.pb(j);
sol = i;
break;
}
}
}
void solve()
{
int i;
for (i = 1; i <= g; ++i)
ret[0][i] = n+1;
for (i = 1; i < 200; i += 20)
rezolva(i);
for (sol = g; sol; --sol)
if (ret[10][sol] < n+1)
{
printf("%d %d\n", sol, ret[10][sol]);
break;
}
for (i = 181; i > 0; i -= 20)
recon(i);
for (i = 0; i < rez.sz; ++i)
printf("%d\n", rez[i]);
}
int main()
{
readdata();
solve();
return 0;
}