| # | Time | Username | Problem | Language | Result | Execution time | Memory | 
|---|---|---|---|---|---|---|---|
| 921515 | Lobo | Parrots (IOI11_parrots) | C++17 | 0 ms | 0 KiB | 
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "encoder.h"
#include "encoderlib.h"
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define fr first
#define sc second
#define int long long
// const int maxn = 1e5+10;
// const int inf = 1e18+10;
static int R;
static int k;
static int base = 1e8;
bool geq(vector<int> s, vector<int> t) {
	if(s.size() > t.size()) return 1;
	if(t.size() > s.size()) return 0;
	for(int i = (int) s.size() -1; i >= 0; i--) {
		if(s[i] > t[i]) return 1;
		if(t[i] > s[i]) return 0;
	}
	return 1;
}
vector<int> mult(vector<int> s, vector<int> t) {
	vector<int> ans((int) s.size()+(int) t.size(),0);
	if(s == vector<int>{0} or t == vector<int>{0}) return vector<int>{0};
	for(int i = 0; i < s.size(); i++) {
		for(int j = 0; j < t.size(); j++) {
			ans[i+j]+= s[i]*t[j];
		}
	}
	for(int i = 0; i < ans.size(); i++) {
		if(ans[i] >= base) {
			if(i+1 == (int) ans.size()) ans.pb(0);
			ans[i+1]+= ans[i]/base;
			ans[i]%= base;
		}
	}
	while(ans.size() > 1 && ans.back() == 0) ans.pop_back();
	return ans;
}
vector<int> add(vector<int> s, vector<int> t) {
	vector<int> ans = s;
	for(int i = 0; i < t.size(); i++) {
		if(i == (int) ans.size()) ans.pb(0);
		ans[i]+= t[i];
	}
	for(int i = 0; i < ans.size(); i++) {
		if(ans[i] >= base) {
			if(i+1 == (int) ans.size()) ans.pb(0);
			ans[i+1]+= ans[i]/base;
			ans[i]%= base;
		}
	}
	while(ans.size() > 1 && ans.back() == 0) ans.pop_back();
	return ans;
}
vector<int> trans(int x) {
	if(x == 0) return vector<int>{0};
	vector<int> ans;
	while(x != 0) {
		ans.pb(x%base);
		x/= base;
	}
	return ans;
}
int transback(vector<int> s) {
	int ans = 0;
	int p10 = 1;
	for(int i = 0; i < s.size(); i++) {
		ans+= p10*s[i];
		p10*= base;
	}
	return ans;
}
vector<int> dp[260][10*64+10];
void precomp() {
	// dp(i,sum) = # de (q_0,q_1,...,q_i) tal que a soma é no maximo sum
	for(int i = 0; i < R; i++) {
		for(int j = 0; j <= k; j++) {
			dp[i][j] = vector<int>{0};
		}
	}
	for(int j = 0; j <= k; j++) {
		dp[0][j] = trans(j+1);
	}
	for(int i = 1; i < R; i++) {
		dp[i][0] = trans(1);
		for(int j = 1; j <= k; j++) {
			dp[i][j] = add(dp[i][j],dp[i][j-1]);
			dp[i][j] = add(dp[i][j],dp[i-1][j]);
		}
	}
}
vector<int> querysmaller(vector<int> q) {
	vector<int> ans = {0};
	int sumq = 0;
	for(int i = R-1; i >= 0; i--) {
		for(int j = 0; j <= q[i]-1 && k-j-sumq >= 0; j++) {
			if(i == 0) ans = add(ans,trans((int)1));
			else ans = add(ans,dp[i-1][k-j-sumq]);
		}
		sumq+= q[i];
	}
	if(sumq <= k) ans = add(ans,trans(1));
	return ans;
}
vector<int> findg(vector<int> g) {
	vector<int> ans(R,0);
	int sumans = 0;
	vector<int> cur = {1};
	for(int i = R-1; i >= 0; i--) {
		ans[i] = 0;
		for(int j = 1; j <= k-sumans; j++) {
			vector<int> newcur;
			if(i == 0) newcur = add(cur,trans(1));
			else newcur = add(cur,dp[i-1][k-sumans-j+1]);
			if(!geq(g,newcur)) break;
			cur = newcur;
			ans[i] = j;
		}
		sumans+= ans[i];
	}
	return ans;
}
void encode(int32_t n, int32_t m[])
{
	k = 5*n;
	R = 220;
	precomp();
	vector<int> vm = trans(0);
	vector<int> p256 = trans(1);
	for(int i = 0; i < n; i++) {
		vm = add(vm,mult(p256,trans(m[i])));
		p256 = mult(p256,trans(256));
	}
	vector<int> ans = findg(add(vm,trans(1)));
	for(int i = 0; i < ans.size(); i++) {
		for(int j = 0; j < ans[i]; j++) {
			send((int32_t) i);
		}
	}	
}
