Cod sursa(job #2012366)

Utilizator lflorin29Florin Laiu lflorin29 Data 18 august 2017 16:37:06
Problema Ghiozdan Scor 88
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.66 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");

const int G = 75000, X = 200;

int n, g;
int ap[X + 2];
int dp[2][G + 3], ant[2][G + 2];
deque<pair<int, int> >dq;

void initLine(bool l, int need) {
	for(int i = 0; i <= need; ++i) {
		if(i > 0) {
			dp[l][i] = n + 1;
		} else dp[l][i] = 0;
		ant[l][i] = i;
	}
}
void solve(int st, int dr, int need) {
	if(st == dr) {
		for(int i=1;i<=ap[st]&&need-st>=0;++i)fout<<st<<'\n',need-=st;
		return;
	}
	int mid = (st + dr) >> 1;
	bool l = 0;
	for(int i = 0; i < 2; ++i) initLine(i, need);
	bool all=1;
	for(int i=st;i<=dr;++i)if(ap[i]&&i<=need)all=0;
	if(all)return;
	for(int i = st; i <= dr; ++i) {
		l ^= 1;
		initLine(l, need);
		for(int r = 0; r < i; ++r) {
			dq.clear();
			for(int u = 0; u * i + r <= need; ++u) {
				int val = u * i + r;
				while(!dq.empty() && dp[l ^ 1][val] - u <= dq.back().first) {
					dq.pop_back();
				}
				dq.push_back(make_pair(dp[l ^ 1][val] - u, val));
				while(!dq.empty() && dq.front().second <= val - (ap[i] + 1) * i) dq.pop_front();
				assert(dq.size());
				dp[l][val] = dq.front().first + u;
				if(i <= mid) {
					ant[l][val] = val;
				} else ant[l][val] = ant[l ^ 1][dq.front().second];
			}
		}
	}
	int w = need;
	if(st == 1 && dr == 200) {
		int weight = need;
		while(weight > 0 && dp[l][weight] == n + 1)--weight;
		fout << weight << ' ' << dp[l][weight] << '\n';
		w = weight;
	}
	solve(st, mid, ant[l][w]);
	solve(mid + 1, dr, need - ant[l][w]);
}
int main() {

	fin >> n >> g;
	for(int i = 1; i <= n; ++i) {
		int x;
		fin >> x;
		++ap[x];
	}
	solve(1, X, g);
}