Problem:
Problem J: Averaging
Problem
アイヅ国には$N$個の島と$N-1$個の橋があり、各島はそれぞれ$1$から$N$までの番号が割り振られている。
  $i$番目の橋は島$u_i$と島$v_i$を双方向に結んでおり、島民は橋を用いて島と島とを行き来することができる。また、橋以外に島と島を行き来する方法はない。
  どの島からどの島へもいくつかの橋を渡ることで到達することができる。
現在、島$i$には$X_i$人の島民がいる。
  各島の環境への負荷を分散させるためにアイヅ国は何人かの国民に別の島へ引越してもらうことにした。
  島$a$に住んでいる人を島$b$に引越しさせるためには島$a$と島$b$の距離と同じ分のコストがかかる。ただし、島$a$と島$b$の距離は島$a$から島$b$へ行くために渡る必要のある橋の数の最小値で定義される。
どの$2$つの島を選んでもそれらの島民の人数の差の絶対値が$1$以下になるように国民に引越してもらいたい。
  このとき、必要なコストの総和の最小値を求めよ。
Input
入力は以下の形式ですべて整数で与えられる。
$N$
$X_1$ $X_2$ ... $X_N$
$u_1$ $v_1$
$u_2$ $v_2$
...
$u_{N-1}$ $v_{N-1}$
$1$行目に島の数$N$が与えられる。
$2$行目には各島の島民の人数を表す$N$個の整数が空白区切りで与えられる。$i$番目の整数$X_i$は島$i$の島民の人数を表す。
$3$行目から続く$N-1$行には各橋がつなぐ島の番号が空白区切りで与えられる。$2+i$行目の入力では、$i$番目の橋が島$u_i$と島$v_i$を双方向に結んでいることを表す。
Constraints
入力は以下の条件を満たす。
$2 \le N \le 5000$
$0 \le X_i \le 10^9$
$1 \le u_i, v_i \le N$
どの島からどの島へもいくつかの橋を渡ることで到達することができる
Output
コストの総和の最小値を1行に出力せよ。
Sample Input 1
5
4 0 4 0 0
1 2
1 3
1 4
2 5
Sample Output 1
7
島$1$の人が$1$人、島$2$へ、
島$1$の人が$1$人、島$5$へ、
島$3$の人が$2$人、島$4$へ引っ越すことでどの$2$つの島を選んでもそれらの島民の人数の差の絶対値が$1$以下になる。
  またこのときのコストの総和は$1+2+2\times2 = 7$であり、これが最小である。
Sample Input 2
7
0 7 2 5 0 3 0
1 2
1 3
1 4
2 5
3 6
3 7
Sample Output 2
10

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> P;
typedef pair<int,int> Pi;
#define rep(i,n) for(ll i=0;i<n;i++)
#define FOR(i,a,b) for(ll i=a;i<b;i++)
#define rrep(i,n) for(ll i=n-1;i>=0;i--)
#define rFOR(i,a,b) for(ll i=a-1;i>=b;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define endl "\n"

template<typename T> inline bool chmax(T &a, T b){if(a<b){a=b;return true;}return false;}
template<typename T> inline bool chmin(T &a, T b){if(a>b){a=b;return true;}return false;}
template<typename T> ostream& operator<<(ostream& s,const complex<T>& d) {return s<<"("<<d.real()<<", "<<d.imag()<< ")";}
template<typename T1, typename T2> ostream& operator<<(ostream& s,const pair<T1,T2>& d) {return s<<"("<<d.first<<", "<<d.second<<")";}
template<typename T> ostream& operator<<(ostream& s, const vector<T>& d){int len=d.size();rep(i,len){s<<d[i];if(i<len-1) s<<" ";}return s;}
template<typename T> ostream& operator<<(ostream& s,const vector<vector<T>>& d){int len=d.size();rep(i,len){s<<d[i]<<endl;}return s;}
template<typename T> ostream& operator<<(ostream& s,const set<T>& v){s<<"{ ";for(auto itr=v.begin();itr!=v.end();++itr) {if (itr!=v.begin()) {s<< ", ";}s<<(*itr);}s<<" }";return s;}
template<typename T> ostream& operator<<(ostream& s,const multiset<T>& v){s<<"{ ";for(auto itr=v.begin();itr!=v.end();++itr) {if (itr!=v.begin()) {s<< ", ";}s<<(*itr);}s<<" }";return s;}
template<typename T1, typename T2> ostream& operator<<(ostream& s,const map<T1,T2>& m){s<<"{"<<endl;for(auto itr=m.begin();itr!=m.end();++itr){s<<" "<<(*itr).first<<" : "<<(*itr).second<<endl;}s<<"}"<<endl;return s;}
template<class T> vector<T> make_vec(size_t n, T a) { return vector<T>(n, a); }
template<class... Ts> auto make_vec(size_t n, Ts... ts) { return vector<decltype(make_vec(ts...))>(n, make_vec(ts...)); }

const ll mod=1'000'000'007;
const ll inf=1'000'000'000'000'000'00;
const int INF=1'000'000'000;
const double EPS=1e-10;
const double PI=acos(-1);

const int N=5100;
ll dp[N][N],ndp[N][N];
ll sum[N],sz[N];

int main(){
    cin.tie(0);ios::sync_with_stdio(false);
    ll n;
    cin>>n;
    vector<ll> x(n);
    ll all=0;
    rep(i,n){
        cin>>x[i];
        all+=x[i];
    }
    vector<vector<ll>> g(n);
    rep(i,n-1){
        ll u,v;
        cin>>u>>v;
        u--,v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    ll k=all%n,num=all/n;
    rep(i,N)rep(j,N) dp[i][j]=inf;
    auto dfs=[&](auto &&dfs,ll v,ll pre)->void{
        vector<ll> tos;
        sz[v]=1;
        sum[v]=x[v];
        for(auto &&to:g[v]){
            if(to==pre) continue;
            dfs(dfs,to,v);
            tos.push_back(to);
            sz[v]+=sz[to];
            sum[v]+=sum[to];
        }
        rep(i,tos.size()+1)rep(j,sz[v]+1) ndp[i][j]=inf;
        ndp[0][0]=0;
        ll cur=1;
        rep(i,tos.size()){
            ll to=tos[i];
            rep(j1,cur+1)rep(j2,sz[to]+1){
                if(ndp[i][j1]==inf || dp[to][j2]==inf) continue;
                if(j1+j2>k) continue;
                chmin(ndp[i+1][j1+j2], ndp[i][j1]+dp[to][j2]);
            }
            cur+=sz[to];
        }
        rep(j,k+1)if(ndp[tos.size()][j]!=inf){
            chmin(dp[v][j], ndp[tos.size()][j]+abs(num*sz[v]+j-sum[v]));
            chmin(dp[v][j+1], ndp[tos.size()][j]+abs(num*sz[v]+j+1-sum[v]));
        }
    };
    dfs(dfs,0,-1);
    cout<<dp[0][k]<<endl;
}
accuracy: 1
time_ms: 90
memory_kb: 408192
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> P;
typedef pair<int,int> Pi;
#define rep(i,n) for(ll i=0;i<n;i++)
#define FOR(i,a,b) for(ll i=a;i<b;i++)
#define rrep(i,n) for(ll i=n-1;i>=0;i--)
#define rFOR(i,a,b) for(ll i=a-1;i>=b;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define endl "\n"

template<typename T> inline bool chmax(T &a, T b){if(a<b){a=b;return true;}return false;}
template<typename T> inline bool chmin(T &a, T b){if(a>b){a=b;return true;}return false;}
template<typename T> ostream& operator<<(ostream& s,const complex<T>& d) {return s<<"("<<d.real()<<", "<<d.imag()<< ")";}
template<typename T1, typename T2> ostream& operator<<(ostream& s,const pair<T1,T2>& d) {return s<<"("<<d.first<<", "<<d.second<<")";}
template<typename T> ostream& operator<<(ostream& s, const vector<T>& d){int len=d.size();rep(i,len){s<<d[i];if(i<len-1) s<<" ";}return s;}
template<typename T> ostream& operator<<(ostream& s,const vector<vector<T>>& d){int len=d.size();rep(i,len){s<<d[i]<<endl;}return s;}
template<typename T> ostream& operator<<(ostream& s,const set<T>& v){s<<"{ ";for(auto itr=v.begin();itr!=v.end();++itr) {if (itr!=v.begin()) {s<< ", ";}s<<(*itr);}s<<" }";return s;}
template<typename T> ostream& operator<<(ostream& s,const multiset<T>& v){s<<"{ ";for(auto itr=v.begin();itr!=v.end();++itr) {if (itr!=v.begin()) {s<< ", ";}s<<(*itr);}s<<" }";return s;}
template<typename T1, typename T2> ostream& operator<<(ostream& s,const map<T1,T2>& m){s<<"{"<<endl;for(auto itr=m.begin();itr!=m.end();++itr){s<<" "<<(*itr).first<<" : "<<(*itr).second<<endl;}s<<"}"<<endl;return s;}
template<class T> vector<T> make_vec(size_t n, T a) { return vector<T>(n, a); }
template<class... Ts> auto make_vec(size_t n, Ts... ts) { return vector<decltype(make_vec(ts...))>(n, make_vec(ts...)); }

const ll mod=1'000'000'007;
const ll inf=1'000'000'000'000'000'00;
const int INF=1'000'000'000;
const double EPS=1e-10;
const double PI=acos(-1);

int main(){
    cin.tie(0);ios::sync_with_stdio(false);
    ll n;
    cin>>n;
    vector<ll> x(n);
    ll all=0;
    rep(i,n){
        cin>>x[i];
        all+=x[i];
    }
    vector<vector<ll>> g(n);
    rep(i,n-1){
        ll u,v;
        cin>>u>>v;
        u--,v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    ll k=all%n,num=all/n;
    auto dp=make_vec(n,k+2,inf);
    auto sum=make_vec(n,0ll);
    auto sz=make_vec(n,0ll);
    auto dfs=[&](auto &&dfs,ll v,ll pre)->void{
        vector<ll> tos;
        for(auto &&to:g[v]){
            if(to==pre) continue;
            dfs(dfs,to,v);
            tos.push_back(to);
        }
        sz[v]=1;
        sum[v]=x[v];
        auto ndp=make_vec(tos.size()+1,k+1,inf);
        ndp[0][0]=0;
        rep(i,tos.size()){
            ll to=tos[i];
            ll x=sz[v],y=sz[to];
            rep(j1,x+1)rep(j2,y+1){
                if(ndp[i][j1]==inf || dp[to][j2]==inf) continue;
                if(j1+j2>k) continue;
                chmin(ndp[i+1][j1+j2], ndp[i][j1]+dp[to][j2]);
            }
            sum[v]+=sum[to];
            sz[v]+=sz[to];
        }
        rep(j,k+1)if(ndp[tos.size()][j]!=inf){
            chmin(dp[v][j], ndp[tos.size()][j]+abs(num*sz[v]+j-sum[v]));
            chmin(dp[v][j+1], ndp[tos.size()][j]+abs(num*sz[v]+j+1-sum[v]));
        }
    };
    dfs(dfs,0,-1);
    //cout<<dp<<endl;
    cout<<dp[0][k]<<endl;
}
accuracy: 0.7924528301886793
time_ms: 70
memory_kb: 117620
final_rank: 20

code_snippet: #include <iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<math.h>
using namespace std;
typedef long long ll;
#define int long long
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef priority_queue<int> PQ;
template<class T>bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

#define fore(i,a) for(auto &i:a)
#define REP(i,n) for(int i=0;i<n;i++)
#define eREP(i,n) for(int i=0;i<=n;i++)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define eFOR(i,a,b) for(int i=(a);i<=(b);++i)
#define SORT(c) sort((c).begin(),(c).end())
#define rSORT(c) sort((c).rbegin(),(c).rend())
#define LB(x,a) lower_bound((x).begin(),(x).end(),(a))
#define UB(x,a) upper_bound((x).begin(),(x).end(),(a))
#define INF 1000000000
#define LLINF 8223372036854775807
#define mod 1000000007
//vector<vector<int> > dp;
//vector<vector<vector<int> > > vvvi;
//dp=vector<vector<int> >(N, vector<int>(M,0));
//vector<pair<int,int> > v;
//v.push_back(make_pair(x,y));
//priority_queue<int,vector<int>, greater<int> > q2;

int N;
VI X;
int all, ave, amari;
int size[5010], sum[5010];
int dp[5010][5010];
int sdp[5010][5010];
vector<VI>G;

void solve(int now, int pa) {
	VI chs;
	size[now] = 1;
	sum[now] = X[now];

	fore(ch, G[now]) {
		if (ch == pa)continue;
		solve(ch, now);
		chs.push_back(ch);
		size[now] += size[ch];
		sum[now] += sum[ch];
	}
	eREP(i, chs.size())eREP(j, size[now])sdp[i][j] = LLINF;
	
	sdp[0][0] = 0;
	int cur = 0;

	REP(i, chs.size()) {
		int ch = chs[i];
		eREP(j, cur) {
			eREP(k, size[ch]) {
				chmin(sdp[i + 1][j + k], sdp[i][j] + dp[ch][k]);
			}
		}
		cur += size[ch];
	}

	eREP(k, size[now]) {
		chmin(dp[now][k], sdp[chs.size()][k] + abs(ave*size[now] + k - sum[now]));
		chmin(dp[now][k + 1], sdp[chs.size()][k] + abs(ave*size[now] + k + 1 - sum[now]));
	}
}






signed main(){
cin.tie(0);
ios::sync_with_stdio(false);

	cin >> N;
	X.resize(N);
	G.resize(N);
	all = 0;
	REP(i, N) {
		cin >> X[i];
		all += X[i];
	}
	ave = all / N;
	amari = all % N;

	REP(i, N - 1) {
		int a, b; cin >> a >> b; a--; b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	REP(i, N)eREP(j, N)dp[i][j] = LLINF;
	solve(0,-1);
	cout << dp[0][amari] << endl;

	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 394936
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
using namespace std;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long INF = 1LL<<60;
int N;
vector<long long> X;
vector<vector<int>> G;
long long all;
long long ave;
int amari;

int size[5100];
long long sum[5100];
long long dp[5100][5100];
long long sdp[5100][5100];

void rec(int v, int p = -1) {
    vector<int> chs;
    size[v] = 1;
    sum[v] = X[v];
    for (auto ch : G[v]) {
        if (ch == p) continue;
        rec(ch, v);
        chs.push_back(ch);
        size[v] += size[ch];
        sum[v] += sum[ch];
    }

    for (int i = 0; i <= chs.size(); ++i)
        for (int j = 0; j <= size[v]; ++j)
            sdp[i][j] = INF;
    sdp[0][0] = 0;
    int cur = 0;
    for (int i = 0; i < chs.size(); ++i) {
        int ch = chs[i];
        for (int j = 0; j <= cur; ++j) {
            for (int k = 0; k <= size[ch]; ++k) {
                chmin(sdp[i+1][j+k], sdp[i][j] + dp[ch][k]);
            }
        }
        cur += size[ch];
    }

    for (int k = 0; k <= size[v]; ++k) {
        chmin(dp[v][k], sdp[chs.size()][k] + abs(ave * size[v] + k - sum[v]));
        chmin(dp[v][k+1], sdp[chs.size()][k] + abs(ave * size[v] + k+1 - sum[v]));
    }
}

int main() {
    cin >> N;
    X.resize(N);
    all = 0;
    for (int i = 0; i < N; ++i) cin >> X[i], all += X[i];
    ave = all / N;
    amari = all % N;
    G.assign(N, vector<int>());
    for (int i = 0; i < N-1; ++i) {
        int a, b; cin >> a >> b; --a, --b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    for (int v = 0; v < N; ++v) for (int i = 0; i <= N; ++i) dp[v][i] = INF;
    rec(0);

    cout << dp[0][amari] << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 401788
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;


template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template<class T> vector<T> make_vec(size_t a) { return vector<T>(a); }
template<class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template<class T, class V>
typename enable_if<is_class<T>::value == 0>::type fill(T &t, const V &v) {
    t = v;
}
template<class T, class V>
typename enable_if<is_class<T>::value != 0>::type fill(T &t, const V &v){
    for (auto &e : t) fill(e, v);
}

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }

const long long INF = 1LL<<60;
int N;
vector<long long> X;
vector<vector<int>> G;
long long all;
long long ave;
int amari;

int size[5100];
long long sum[5100];
long long dp[5100][5100];
long long sdp[5100][5100];

void rec(int v, int p = -1) {
    vector<int> chs;
    size[v] = 1;
    sum[v] = X[v];
    for (auto ch : G[v]) {
        if (ch == p) continue;
        rec(ch, v);
        chs.push_back(ch);
        size[v] += size[ch];
        sum[v] += sum[ch];
    }

    for (int i = 0; i <= chs.size(); ++i)
        for (int j = 0; j <= size[v]; ++j)
            sdp[i][j] = INF;
    sdp[0][0] = 0;
    int cur = 0;
    for (int i = 0; i < chs.size(); ++i) {
        int ch = chs[i];
        for (int j = 0; j <= cur; ++j) {
            for (int k = 0; k <= size[ch]; ++k) {
                chmin(sdp[i+1][j+k], sdp[i][j] + dp[ch][k]);
            }
        }
        cur += size[ch];
    }

    for (int k = 0; k <= size[v]; ++k) {
        chmin(dp[v][k], sdp[chs.size()][k] + abs(ave * size[v] + k - sum[v]));
        chmin(dp[v][k+1], sdp[chs.size()][k] + abs(ave * size[v] + k+1 - sum[v]));
    }
}

int main() {
    cin >> N;
    X.resize(N);
    all = 0;
    for (int i = 0; i < N; ++i) cin >> X[i], all += X[i];
    ave = all / N;
    amari = all % N;
    G.assign(N, vector<int>());
    for (int i = 0; i < N-1; ++i) {
        int a, b; cin >> a >> b; --a, --b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    for (int v = 0; v < N; ++v) for (int i = 0; i <= N; ++i) dp[v][i] = INF;
    rec(0);

    cout << dp[0][amari] << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 401696
final_rank: 14

code_snippet: #include "bits/stdc++.h"

using namespace std;
using ll = long long;

#define REP(i,n) for(ll i =0;i<n;++i)

constexpr ll INF = 1e9 + 1;
vector<ll> x, cnt, sum;
ll  a;
void init(vector<vector<int>>& g, int i, int p) {
	ll cnt0 = 1, sum0 = x[i];
	REP(j, g[i].size()) {
		if (g[i][j] == p)continue;
		init(g, g[i][j], i);
		cnt0 += cnt[g[i][j]];
		sum0 += sum[g[i][j]];
	}
	cnt[i] = cnt0;
	sum[i] = sum0;
}

ll f(int v, int i) {
	//cout<<v<<endl;
	return abs(a * cnt[v] + i - sum[v]);
}

vector<ll> merge(vector<ll>& l, vector<ll>& r, int rv) {
	//cout<<l.size()<<" "<<r.size()<<endl;
	vector<ll> res(l.size() + r.size() - 1, INF * INF);
	REP(i, l.size())REP(j, r.size()) {
		res[i + j] = min(res[i + j], l[i] + r[j] + f(rv, j));
	}

	//cout<<"end"<<endl;
	return res;

}
void dfs(vector<vector<int>>& g, vector<vector<ll>>& dp, int v, int p) {
	vector<ll> res(2, 0);
	REP(i, g[v].size()) {
		if (g[v][i] == p)continue;
		dfs(g, dp, g[v][i], v);
		res = merge(res, dp[g[v][i]], g[v][i]);
		// cout<<g[v][i]<<endl;
	}
	dp[v] = res;
}
int main() {
	int n; cin >> n;
	x.resize(n);
	cnt.resize(n);
	sum.resize(n);
	REP(i, n)cin >> x[i];
	vector<vector<int>>g(n);
	REP(i, n - 1) {
		int a, b; cin >> a >> b;
		a--; b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	init(g, 0, -1);
	a = sum[0] / n;
	vector<vector<ll>> dp(n);
	dfs(g, dp, 0, -1);
	cout << dp[0][sum[0] % n] << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 107248
final_rank: 4

code_snippet: #include "bits/stdc++.h"

#pragma warning(disable:4996)
using namespace std;
using ld = long double;

typedef vector<pair<long long int,long long int>> DP;

DP connect(const DP&l, const DP&r) {
	DP k(l.size()+r.size()-1,make_pair(1e18,1e18));
	for (int i = 0; i < l.size(); ++i) {
		for (int j = 0; j < r.size(); ++j) {
			auto x = make_pair(l[i].first + r[j].first, l[i].second + r[j].second);

			k[i + j] = min(k[i + j], x);

		}
	}
	return k;
}
DP dfs(const int now, const int from,
	const vector<vector<int>>&edges,vector<int>&overs) {

	long long int over_num=overs[now];
	DP v(2);
	v[0]=make_pair(over_num,0);
	v[1]=make_pair(over_num-1,0);

	vector<vector<pair<long long int,long long int>>>ps;
	for (auto e : edges[now]) {
		if(e==from)continue;
		ps.push_back(dfs(e,now,edges,overs));
	}
	sort(ps.begin(), ps.end(), [](const vector < pair<long long int, long long int>>&l, const vector<pair<long long int, long long int>>&r) {
		return l.size()<r.size();
	});
	for (auto p : ps) {
		v=connect(v,p);
	}
	for (auto &k : v) {
		k.second+=abs(k.first);
	}
	return v;
}
int main() {
	int N;cin>>N;
	vector<int>nums;
	{
		for (int i = 0; i < N; ++i) {
			int a;cin>>a;
			nums.push_back(a);
		}
		long long int sum=accumulate(nums.begin(),nums.end(),0ll);
		for (auto &n : nums) {
			n-=sum/N;
		}
	}
	vector<vector<int>>edges(N);
	for (int i = 0; i < N - 1; ++i) {
		int a,b;cin>>a>>b;a--;b--;
		edges[a].push_back(b);
		edges[b].push_back(a);
	}
	DP ans=dfs(0,-1,edges,nums);
	for (int i = 0; i < ans.size(); ++i) {
		if(ans[i].first==0)cout<<ans[i].second<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4264
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define INF 10000000000000007LL
using namespace std;
typedef long long ll;
typedef pair<ll,short> P;
typedef pair<int,short> P2;

int n;
vector<int> G[5005];
ll x[5005];
int u[5005],v[5005];
ll dp[5005][5005];
ll tmp[5005];
ll subsum[5005];
int child[5005];
ll sum;
ll min_v=0;
int tp=0;

ll labs(ll v){
	if(v<0LL)return -v;
	return v;
}

ll dfs(int v,int p){
	ll su=x[v];
	for(int i=0;i<G[v].size();i++){
		int nv=G[v][i];
		if(nv==p)continue;
		su+=dfs(G[v][i],v);
	}
	return subsum[v]=su;
}

int dfs1(int v,int p){
	int su=1;
	for(int i=0;i<G[v].size();i++){
		int nv=G[v][i];
		if(nv==p)continue;
		su+=dfs1(G[v][i],v);
	}
	return child[v]=su;
}

void dfs2(int v,int p){
	int siz=0;
	for(int i=0;i<G[v].size();i++){
		int nv=G[v][i];
		if(nv==p)continue;
		dfs2(G[v][i],v);
		for(int j=0;j<=n;j++){
			tmp[j]=INF;
		}
		for(int j=0;j<=siz;j++){
			for(int k=0;k<=min(tp,child[nv]);k++){
				ll nc=labs(subsum[nv]-child[nv]*min_v-k);
				tmp[j+k]=min(dp[v][j]+dp[nv][k]+nc,tmp[j+k]);
			}
		}
		for(int j=0;j<=n;j++){
			dp[v][j]=tmp[j];
		}
		siz+=child[nv];
	}
	for(int i=n;i>=1;i--){
		dp[v][i]=min(dp[v][i],dp[v][i-1]);
	}
}

int main(void){
	scanf("%d",&n);
	int S=n;
	int T=n+1;
	sum=0;
	for(int i=0;i<n;i++){
		scanf("%lld",&x[i]);
		sum+=x[i];
	}
	tp=(ll)sum%n;
	min_v=(ll)sum/n;
	for(int i=0;i<n-1;i++){
		scanf("%d%d",&u[i],&v[i]);
		u[i]--;
		v[i]--;
		G[u[i]].push_back(v[i]);
		G[v[i]].push_back(u[i]);
	}
	dfs(0,-1);
	dfs1(0,-1);
	dfs2(0,-1);
	printf("%lld\n",dp[0][sum%n]);
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 199744
final_rank: 8

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 5010

vector<int> tree[SIZE];

int n, x[SIZE];
ll dp[SIZE][SIZE][2];
ll ave, num_plus;

pair<int, ll> dfs(int now = 0, int back = -1, int cost = INF){ //{numOfChilds, sumOfChildsX} 
  ll numOfChilds = 0, sum = 0;

  dp[now][0][0] = 0;
  
  for(int to : tree[now]){
    if(back == to) continue;
    auto res = dfs(to, now, 1);

    for(int i=0;i<=numOfChilds;i++){
      for(int j=0;j<=res.first;j++){
        dp[now][i+j][1] = min(dp[now][i+j][1], dp[now][i][0] + dp[to][j][0]);
      }
    }

    for(int i=0;i<=numOfChilds+res.first;i++){
      dp[now][i][0] = dp[now][i][1];
      dp[now][i][1] = LLINF;
    }
    
    numOfChilds += res.first;
    sum += res.second;
  }

  sum += x[now];
  numOfChilds += 1;
  
  for(int i=numOfChilds;i>=0;i--){
    ll add_cost = abs(sum - (ave*numOfChilds + (i+1))) * cost;
    dp[now][i+1][0] = min(dp[now][i+1][0], dp[now][i][0] + add_cost);
    ll add_cost2 = abs(sum - (ave*numOfChilds + i)) * cost;
    dp[now][i][0] = dp[now][i][0] + add_cost2; 
  }
  
  return {numOfChilds, sum};
}

int main(){
  ll sumx = 0;
  
  scanf("%d", &n);

  for(int i=0;i<n;i++){
    scanf("%d", x+i);
    sumx += x[i];
  }

  ave = sumx / n;
  num_plus = sumx % n;
  
  for(int i=0;i<n-1;i++){
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    tree[u].push_back(v);
    tree[v].push_back(u);
  }

  for(int i=0;i<=n;i++)
    for(int j=0;j<=n;j++)
      dp[i][j][0] = dp[i][j][1] = LLINF;

  dfs();

  cout << dp[0][num_plus][0] << endl;
  
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 395596
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

ll N,X[5001],R[5001],cnt[5001],sumr[5001];
ll dp[5001][5001];
ll dp2[2][5001];
ll tot=0,p=0,K;
vector<int> g[5001];

void dfs(int v,int pre){
  cnt[v]=1; sumr[v]=R[v];
  for(int nv : g[v]){
    if(nv==pre)continue;
    dfs(nv,v);
    cnt[v]+=cnt[nv]; sumr[v]+=sumr[nv];
  }
  int crt=0,nxt=1;
  rep(j,cnt[v]+1)dp2[crt][j]=INF;
  dp2[crt][0]=0;
  for(int nv : g[v]){
    if(nv==pre)continue;
    rep(j,cnt[v]+1)dp2[nxt][j]=INF;
    rep(j,cnt[v]+1){
      if(dp2[crt][j]==INF)break;
      rep(k,cnt[nv]+1){
        if(j+k<=cnt[v])minch(dp2[nxt][j+k],dp2[crt][j]+dp[nv][k]+llabs(sumr[nv]-k));
        else break;
      }
    }
    swap(crt,nxt);
  }
  rep(j,cnt[v]+1){
    dp[v][j]=dp2[crt][j];
    if(j>0)minch(dp[v][j],dp2[crt][j-1]);
  }
}

int main(){
  scanf("%lld",&N);
  rep(i,N){
    scanf("%lld",X+i);
    p+=X[i]; tot+=X[i];
  }
  p/=N; K=tot-N*p;
  rep(i,N){
    R[i]=X[i]-p;
  }
  rep(i,N-1){
    int a,b;
    scanf("%d%d",&a,&b);
    a--;b--;
    g[a].push_back(b); g[b].push_back(a);
  }
  dfs(0,-1);
  cout<<dp[0][K]<<endl;
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 121020
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
const Int MAX = 5050;
const Int INF = 1e17;
Int dp[MAX][MAX];
signed main(){
  Int n;
  cin>>n;
  vector<Int> a(n);
  for(Int i=0;i<n;i++) cin>>a[i];

  Int s=0;
  for(Int i=0;i<n;i++) s+=a[i];
  Int x=s/n;
  
  vector<vector<Int> > G(n);
  for(Int i=1;i<n;i++){
    Int a,b;
    cin>>a>>b;
    a--;b--;
    G[a].emplace_back(b);
    G[b].emplace_back(a);
  }

  vector<Int> sz(n,1);
  function<void(Int, Int)> dfs=
    [&](Int v,Int p){      
      for(Int u:G[v])
	if(u!=p) dfs(u,v),a[v]+=a[u];
      
      for(Int i=0;i<MAX;i++) dp[v][i]=INF;
      dp[v][0]=dp[v][1]=0;
      for(Int u:G[v]){
	if(u==p) continue;
	vector<Int> nx(sz[v]+sz[u]+2,INF);
	for(Int i=0;i<=sz[v];i++)
	  for(Int j=0;j<=sz[u];j++)
	    chmin(nx[i+j],dp[v][i]+dp[u][j]+abs(a[u]-((x+1)*j+x*(sz[u]-j))));
	
	sz[v]+=sz[u];
	for(Int i=0;i<=sz[v];i++) dp[v][i]=nx[i];
      }
    }; 

  dfs(0,-1);  
  cout<<dp[0][s%n]<<endl;
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 201124
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define FORR(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)

#define CHMIN(a,b) (a)=min((a),(b))
#define CHMAX(a,b) (a)=max((a),(b))

#define MOD 1000000007

int n;
ll x[5252];
vi g[5252];

ll sum, a;

int cnt[5252];
ll subsum[5252];

void dfs1(int p, int bef){
  cnt[p] = 1;
  subsum[p] = x[p];
  for(int to : g[p])if(to != bef){
    dfs1(to, p);
    cnt[p] += cnt[to];
    subsum[p] += subsum[to];
  }
}

ll dp[5252][5252];  // dp[p][b] := b個がa+1, cnt[p]-b個がaになる時の最小コスト, b<=cnt[p]
ll tmp[5252];
void dfs2(int p, int bef){
  dp[p][0] = dp[p][1] = 0;
  int m = 2;
  for(int to : g[p])if(to != bef){
    dfs2(to, p);
    // merge
    REP(i,cnt[to]+m)tmp[i] = 1ll<<60;
    REP(i,cnt[to]+1)REP(j,m){
      CHMIN(tmp[i+j], dp[to][i]+dp[p][j]);
    }
    REP(i,cnt[to]+m)dp[p][i] = tmp[i];
    m += cnt[to];
  }
  REP(i,m){
    ll sm = a*cnt[p] + i;
    dp[p][i] += abs(sm-subsum[p]);
  }
}

int main(){
  scanf("%d",&n);
  REP(i,n)scanf("%lld",x+i);
  REP(i,n-1){
    int u,v;
    scanf("%d%d",&u,&v);
    --u;--v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  sum = accumulate(x,x+n,0ll);
  a = sum/n;
  dfs1(0,-1);
  dfs2(0,-1);
  printf("%lld\n",dp[0][sum%n]);
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 121424
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define INF 10000000000000007LL
#define INF2 5005LL
using namespace std;
typedef long long ll;
typedef pair<ll,int> P;

struct RadixHeap{
	vector<P> v[65];
	int sz;
	int last;
	RadixHeap(){
		last=0;
		sz=0;
	}
	int bsr(int x){
		if(x==0)return -1;
		return 63-__builtin_clz(x);
	}
	void push(P p){
		assert(last<=p.first);
		sz++;
		v[bsr(p.first^last)+1].push_back(p);
	}
	P top(){
		return pop(false);
	}
	P pop(bool flag=true){
		assert(sz);
		if(!v[0].size()){
			int i=1;
			while(!v[i].size())i++;
			last=min_element(v[i].begin(),v[i].end())->first;
			for(int j=0;j<v[i].size();j++){
				v[bsr(v[i][j].first^last)+1].push_back(v[i][j]);
			}
			v[i].clear();
		}
		P best=v[0].back();
		if(flag){
			v[0].pop_back();
			sz--;
		}
		return best;
	}
};


struct edge{
	int to,rev;
	ll cap,cost;
	edge(){}
	edge(int t,ll c,ll co,int r){
		to=t;
		cap=c;
		cost=co;
		rev=r;
	}
};

struct mincostflow{
	edge G[5005][5005];
	int siz[5005];
	ll h[5005];
	ll dist[5005];
	int prevv[5005],preve[5005];

	void add_edge(int from,int to,ll cap,ll cost){
		//printf("%d %d %lld %lld\n",from,to,cap,cost);
		G[from][siz[from]++]=edge(to,cap,cost,siz[to]);
		G[to][siz[to]++]=edge(from,0,-cost,siz[from]-1);
	}

	ll min_cost_flow(int s,int t,ll f,int V){
		ll res=0;
		fill(h,h+V,0);
		//printf("%d %d %lld %d\n",s,t,f,V);
		while(f>0LL){
			//priority_queue<P,vector<P>,greater<P> > que;
			RadixHeap que;
			fill(dist,dist+V,INF);
			dist[s]=0;
			que.push(P(0,s));
			while(que.sz>0){
				P p=que.pop();
				int v=p.second;
				if(dist[v]<p.first)continue;
				for(int i=0;i<siz[v];i++){
					edge &e=G[v][i];
					if(e.cap>0 && dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
						dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
						prevv[e.to]=v;
						preve[e.to]=i;
						que.push(P(dist[e.to],e.to));
					}
				}
			}
			if(dist[t]==INF)return -1;
			for(int v=0;v<V;v++){
				h[v]+=dist[v];
			}
			ll d=f;
			for(int v=t;v!=s;v=prevv[v]){
				d=min(d,G[prevv[v]][preve[v]].cap);
			}
			f-=d;
			res+=d*h[t];
			for(int v=t;v!=s;v=prevv[v]){
				edge &e=G[prevv[v]][preve[v]];
				e.cap-=d;
				G[v][e.rev].cap+=d;
			}
		}
		return res;
	}
};

mincostflow mi;

int n;
ll x[5005];
int u[5005],v[5005];

int main(void){
	scanf("%d",&n);
	int S=n;
	int T=n+1;
	ll sum=0;
	for(int i=0;i<n;i++){
		scanf("%lld",&x[i]);
		
		sum+=x[i];
	}
	ll sum2=0;
	for(int i=0;i<n;i++){
		if(x[i]>=(sum/n)){
			if(x[i]-sum/n>0)mi.add_edge(S,i,x[i]-(sum/n),0);
			sum2+=sum/n;
		}
		if(x[i]<(sum/n)){
			sum2+=x[i];
			mi.add_edge(i,T,(ll)(sum/n)-x[i],0);
		}
		mi.add_edge(i,T,1,INF2);
	}
	for(int i=0;i<n-1;i++){
		scanf("%d%d",&u[i],&v[i]);
		u[i]--;
		v[i]--;
		mi.add_edge(u[i],v[i],INF,1);
		mi.add_edge(v[i],u[i],INF,1);
	}
	//printf("%lld %lld\n",sum,sum2);
	ll ans=mi.min_cost_flow(S,T,sum-sum2,T+1);
	printf("%lld\n",ans-INF2*(sum-(sum/n)*n));
	return 0;
}
accuracy: 0.8679245283018868
time_ms: 1870
memory_kb: 24044
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define X first
#define Y sevcond
#define pb emplace_back
#define eb pb
#define rep(X,Y) for(int X=0;X<(Y);++X)
#define reps(X,O,Y) for(int X=(O);X<(Y);++X)
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()

using namespace std;
using ll=long long;
const ll INF=1e18;

int main(){
	int n;
	cin>>n;
	vector<int> xs(n);
	using Graph=vector<vector<int>>;
	Graph g(n);
	rep(i,n) cin>>xs[i];
	int t;
	{
		ll s=accumulate(all(xs),0ll);
		rep(i,n) xs[i]-=s/n;
		t=s%n;
	}
	rep(i,n-1){
		int x,y;
		cin>>x>>y; --x; --y;
		g[x].pb(y);
		g[y].pb(x);
	}
	vector<ll> sum(n),sz(n);
	{
		function<void(int,int)> dfs=
			[&](int v,int p){
				++sz[v]; sum[v]+=xs[v];
				for(int w:g[v])if(w!=p){
						dfs(w,v);
						sum[v]+=sum[w];
						sz[v]+=sz[v];
					}
			};
		dfs(0,-1);
	}
	vector<vector<ll>> dp(n);
	function<void(int,int)> dfs=
		[&](int v,int p){
			dp[v].pb(0);
			for(int w:g[v])if(w!=p){
					dfs(w,v);
					auto tmp=dp[v];
					dp[v].clear();
					dp[v].resize(tmp.size()+dp[w].size(),INF);
					rep(i,tmp.size())rep(j,dp[w].size()){
						dp[v][i+j]=min(dp[v][i+j],tmp[i]+dp[w][j]+abs(j-sum[w]));
						dp[v][i+j+1]=min(dp[v][i+j+1],tmp[i]+dp[w][j]+abs(j+1-sum[w]));
					}
				}
		};
	dfs(0,-1);
	// rep(i,n){
	// 	cout<<i<<endl;
	// 	for(auto x:dp[i]) cout<<x<<",";cout<<endl;
	// }
	cout<<min(dp[0][t],dp[0][max(0,t-1)])<<endl;
}
accuracy: 1
time_ms: 50
memory_kb: 101832
final_rank: 3

code_snippet: #include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<bitset>
#include<stack>
#include<memory>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
/*
cout<<fixed<<setprecision(20);
cin.tie(0);
ios::sync_with_stdio(false);
*/
const llint mod=1000000007;
const llint big=2.19e18+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-15;
template <class T,class U>bool mineq(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool maxeq(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>llint LBI(vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>llint UBI(vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}
vector<llint>X;
vector<vector<int>>go;
pair<vector<llint>,llint>dfs(int ter,int per){
	llint ofset=X[ter];
	vector<llint>ans(2);
	int i,j;
	for(auto it:go[ter]){
		if(it==per){continue;}
		auto ret=dfs(it,ter);
		ofset+=ret.sec;
		//ここでマージする、本当は凸性を使ったマージができるが、O(n^2)が間に合うし、凸性使ってもO(n^2)ので使わない
		vector<llint>iti(ans.size()+ret.fir.size()-1,big);
		for(i=0;i<ans.size();i++){
			for(j=0;j<ret.fir.size();j++){
				mineq(iti[i+j],ans[i]+ret.fir[j]);
			}
		}
		ans=move(iti);
	}
	for(i=0;i<ans.size();i++){ans[i]+=abs(ofset-i);}
	return mp(ans,ofset);
}
int main(void){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n,i;cin>>n;
	X.res(n);
	go.res(n);
	llint wa=0;
	for(i=0;i<n;i++){cin>>X[i];wa+=X[i];}
	for(i=0;i<n;i++){X[i]-=wa/n;}
	for(i=0;i<n-1;i++){
		int u,v;cin>>u>>v;u--;v--;
		go[u].pub(v);
		go[v].pub(u);
	}
	cout<<dfs(0,-1).fir[wa%n]<<endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4164
final_rank: 1

code_snippet: #include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<bitset>
#include<stack>
#include<memory>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
/*
cout<<fixed<<setprecision(20);
cin.tie(0);
ios::sync_with_stdio(false);
*/
const llint mod=1000000007;
const llint big=2.19e15+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-15;
template <class T,class U>bool mineq(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool maxeq(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>llint LBI(vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>llint UBI(vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}
vector<llint>X;
vector<vector<int>>go;
pair<vector<llint>,llint>dfs(int ter,int per){
	llint ofset=X[ter];
	vector<llint>ans(2);
	int i,j;
	for(auto it:go[ter]){
		if(it==per){continue;}
		auto ret=dfs(it,ter);
		ofset+=ret.sec;
		//ここでマージする、本当は凸性を使ったマージができるが、O(n^2)が間に合うし、凸性使ってもO(n^2)ので使わない
		vector<llint>iti(ans.size()+ret.fir.size()-1,big);
		
		for(i=0;i<ans.size();i++){
			for(j=0;j<ret.fir.size();j++){
				mineq(iti[i+j],ans[i]+ret.fir[j]);
			}
		}
		ans=move(iti);
	}
	for(i=0;i<ans.size();i++){ans[i]+=abs(ofset-i);}
	return mp(ans,ofset);
}
int main(void){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n,i;cin>>n;
	X.res(n);
	go.res(n);
	llint wa=0;
	for(i=0;i<n;i++){cin>>X[i];wa+=X[i];}
	for(i=0;i<n;i++){X[i]-=wa/n;}
	for(i=0;i<n-1;i++){
		int u,v;cin>>u>>v;u--;v--;
		go[u].pub(v);
		go[v].pub(u);
	}
	cout<<dfs(0,-1).fir[wa%n]<<endl;
	return 0;
}
accuracy: 0.9811320754716981
time_ms: 30
memory_kb: 4124
final_rank: 17

code_snippet: //これもっと解かれててよくないか
#include<bits/stdc++.h>
#define X first
#define Y sevcond
#define pb emplace_back
#define eb pb
#define rep(X,Y) for(int X=0;X<(Y);++X)
#define reps(X,O,Y) for(int X=(O);X<(Y);++X)
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()

using namespace std;
using ll=long long;
const ll INF=1e15;

int main(){
	int n;
	cin>>n;
	vector<int> xs(n);
	using Graph=vector<vector<int>>;
	Graph g(n);
	rep(i,n) cin>>xs[i];
	int t;
	{
		ll s=accumulate(all(xs),0ll);
		rep(i,n) xs[i]-=s/n;
		t=s%n;
	}
	rep(i,n-1){
		int x,y;
		cin>>x>>y; --x; --y;
		g[x].pb(y);
		g[y].pb(x);
	}
	vector<ll> sum(n),sz(n);
	{
		function<void(int,int)> dfs=
			[&](int v,int p){
				++sz[v]; sum[v]+=xs[v];
				for(int w:g[v])if(w!=p){
						dfs(w,v);
						sum[v]+=sum[w];
						sz[v]+=sz[v];
					}
			};
		dfs(0,-1);
	}
	vector<vector<ll>> dp(n);
	function<void(int,int)> dfs=
		[&](int v,int p){
			dp[v].pb(0);
			for(int w:g[v])if(w!=p){
					dfs(w,v);
					auto tmp=dp[v];
					dp[v].clear();
					dp[v].resize(tmp.size()+dp[w].size(),INF);
					rep(i,tmp.size())rep(j,dp[w].size()){
						dp[v][i+j]=min(dp[v][i+j],tmp[i]+dp[w][j]+abs(j-sum[w]));
						dp[v][i+j+1]=min(dp[v][i+j+1],tmp[i]+dp[w][j]+abs(j+1-sum[w]));
					}
				}
		};
	dfs(0,-1);
	// rep(i,n){
	// 	cout<<i<<endl;
	// 	for(auto x:dp[i]) cout<<x<<",";cout<<endl;
	// }
	cout<<min(dp[0][t],dp[0][max(0,t-1)])<<endl;
}
accuracy: 0.9811320754716981
time_ms: 50
memory_kb: 101724
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;


typedef long long ll;
const int MAX_V = 5005;

typedef pair< int , int > P;

const ll INF=1000000000LL;

const ll capmx=10000000000000LL;

struct edge { ll to,cap,cost,rev; };

int V;
vector<edge> G[MAX_V];
ll h[MAX_V];
int dist[MAX_V];
ll prevv[MAX_V],preve[MAX_V];

void add_edge(ll from,ll to,ll cap,ll cost, bool flag = false){
  G[from].push_back((edge){to,cap,cost,(ll)G[to].size()});

  G[to].push_back((edge){from,0,-cost,(ll)G[from].size()-1});
}

ll min_cost_flow(int s,int t,ll &f){
  ll res = 0;
  fill(h,h+V,0);
  
  while(f>0){

    queue<int> que;
    
    memset( dist , 1 , sizeof( dist ) );
    dist[s]=0;
    que.push( s );
    while( !que.empty() ){
      int key = que.front(); que.pop();
      int v = key%MAX_V;
      int cost = key/MAX_V;
      
      if(dist[v]<cost)continue;
      if(v==t)continue;
      
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap>0&&dist[e.to] > dist[v]+e.cost+h[v]-h[e.to]){
          dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];

          prevv[e.to]=v;
          preve[e.to]=i;
          que.push(dist[e.to]*MAX_V+e.to);
        }
      }
    }
    if(dist[t]==dist[MAX_V-1]){
      break;
    }
    for(int v=0;v<V;v++){
      h[v]+=dist[v];
    }
    ll d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,(ll)G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    res+=(ll)d*h[t];
    for(int v=t;v!=s;v=prevv[v]){

      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      if( prevv[v] == s )break;
      G[v][e.rev].cap += d;
    }
  }

  return res;
}




ll In[5000];
ll Out[5000];
ll Size[5000];
vector<int> g[5000];
int parent[5000];

void dfs(int pos,int prev){
  parent[pos]=prev;
  for(int i=0;i<(int)g[pos].size();i++){
    int to=g[pos][i];
    if(to==prev)continue;
    dfs(to,pos);
    In[pos]+=In[to];
    Out[pos]+=Out[to];
    Size[pos]+=Size[to];
  }
}


int main(){
  ll n, sum=0;
  ll x[5000];
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>x[i];
    sum+=x[i];
  }
  
  int si=n;
  int ti=n+1;
  
  V=ti+1;
  
  for(int i=0;i+1<n;i++){
    int u,v;
    cin>>u>>v;
    u--;
    v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }


  int root = rand() % n;
  
  ll tmp=sum;
  for(int i=0;i<n;i++){
    Size[i]=1;
    In[i]=Out[i]=0;
    
    ll p= min(sum/n , x[i]);
    tmp-=p;
    if(x[i]-p>0){
      add_edge(si,i,x[i]-p,0, true);
      In[i] = x[i]-p;
    }

    if( sum/n-p > 0 ){
      add_edge(i,ti, sum/n-p , 0 );
      Out[i] = (sum/n-p);
    }
  }
  
  dfs( root ,-1);
  

  for(int i=0;i<n;i++){
    if( i== root )continue;
    
    ll U=In[i]-Out[i];
    //    add_edge( i, parent[i], capmx , 1);
    //    add_edge( parent[i], i, capmx , 1);
    
    if( U  <= 0  ){
      add_edge( parent[i],i , -U+min(Size[i],sum%n)  , 1);

    }else{
      add_edge( i,parent[i] , U , 1);
      
      if( min(sum%n,Size[i])-U >0 ){
        add_edge( parent[i], i, min(sum%n,Size[i])-U , 1);
      }
    }
    
  }
  
  for(int i=0;i<n;i++) add_edge(i,ti, 1, 5000LL);

  ll ans=min_cost_flow(si,ti,tmp);

  ans -= 5000LL * (sum%n);

  cout<< ans <<endl;
  return 0;
}
accuracy: 1
time_ms: 1330
memory_kb: 5020
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned int uint;

int bar(uint x){
  if(x==0)return -1;
  return 31- __builtin_clz(x);
}
struct RadixHeapInt {
  uint v[33][5005];
  uint w[33];
  uint last,sz;
  
  RadixHeapInt() {
    memset( w , 0, sizeof(w) );
    last = sz = 0;
  }
  
  void push(uint x){
    sz++;
    v[ bar(x^last)+1 ][ w[ bar(x^last)+1 ] ]=x;
    w[ bar(x^last)+1 ]++;
  }
  
  uint pop(){
    if( !w[0] ){
      int i=1;
      while( !w[i] )i++;
      uint new_last =
        *min_element(v[i] , v[i]+w[i] );
      
      for(int j=0;j<(int)w[i];j++){
        uint x=v[i][j];
        v[ bar(x^new_last)+1 ][ w[bar(x^new_last)+1] ]=x;
        w[bar(x^new_last)+1]++;
      }
      last = new_last;
      w[i]=0;
    }
    sz--;
    w[0]--;
    return last;
  }
};

typedef long long ll;
const int MAX_V = 5005;

typedef pair< int , int > P;

const ll INF=1000000000LL;

const ll capmx=10000000000000LL;

struct edge { ll to,cap,cost,rev; };

int V;
vector<edge> G[MAX_V];
ll h[MAX_V];
int dist[MAX_V];
ll prevv[MAX_V],preve[MAX_V];

void add_edge(ll from,ll to,ll cap,ll cost, bool flag = false){
  G[from].push_back((edge){to,cap,cost,(ll)G[to].size()});
  if( flag )return;
  G[to].push_back((edge){from,0,-cost,(ll)G[from].size()-1});
}


RadixHeapInt que;

ll min_cost_flow(int s,int t,ll &f){
  ll mini = INF;
  ll res = 0;
  //fill(h,h+V,0);
  //  h[t]=0;
  
  while(f>0){
    //    que.last=0;

    queue<int> que;
    
    memset( dist , 1 , sizeof( dist ) );
    dist[s]=0;
    que.push( s );
    while( !que.empty() ){
      uint key = que.front(); que.pop();
      int v = key%MAX_V;
      int cost = key/MAX_V;
      if(dist[v]<cost)continue;
      if(v==t)continue;
      
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap>0&&dist[e.to] > dist[v]+e.cost+h[v]-h[e.to]){
          dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];

          mini  = min( mini , e.cost+h[v]-h[e.to] );
          prevv[e.to]=v;
          preve[e.to]=i;
          que.push(dist[e.to]*MAX_V+e.to);
        }
      }
    }
    if(dist[t]==dist[MAX_V-1]){
      break;
    }
    for(int v=0;v<V;v++){
      h[v]+=dist[v];
    }
    ll d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,(ll)G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    res+=(ll)d*h[t];
    for(int v=t;v!=s;v=prevv[v]){

      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      if( prevv[v] == s )break;
      G[v][e.rev].cap += d;
    }
  }

  return res;
}




ll In[5000];
ll Out[5000];
ll Size[5000];
vector<int> g[5000];
int parent[5000];

void dfs(int pos,int prev){
  parent[pos]=prev;
  for(int i=0;i<(int)g[pos].size();i++){
    int to=g[pos][i];
    if(to==prev)continue;
    dfs(to,pos);
    In[pos]+=In[to];
    Out[pos]+=Out[to];
    Size[pos]+=Size[to];
  }
}


int main(){
  ll n, sum=0;
  ll x[5000];
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>x[i];
    sum+=x[i];
  }
  
  int si=n;
  int ti=n+1;
  
  V=ti+1;
  
  for(int i=0;i+1<n;i++){
    int u,v;
    cin>>u>>v;
    u--;
    v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }


  int root = rand() % n;
  
  ll tmp=sum;
  for(int i=0;i<n;i++){
    Size[i]=1;
    In[i]=Out[i]=0;
    
    ll p= min(sum/n , x[i]);
    tmp-=p;
    if(x[i]-p>0){
      add_edge(si,i,x[i]-p,0, true);
      In[i] = x[i]-p;
    }

    if( sum/n-p > 0 ){
      add_edge(i,ti, sum/n-p , 0 );
      Out[i] = (sum/n-p);
    }
  }
  
  dfs( root ,-1);
  

  for(int i=0;i<n;i++){
    if( i== root )continue;
    
    ll U=In[i]-Out[i];
    //    add_edge( i, parent[i], capmx , 1);
    //    add_edge( parent[i], i, capmx , 1);
    
    if( U  <= 0  ){
      add_edge( parent[i],i , -U+min(Size[i],sum%n)  , 1);

    }else{
      add_edge( i,parent[i] , U , 1);
      
      if( min(sum%n,Size[i])-U >0 ){
        //add_edge( parent[i], i, min(sum%n,Size[i])-U , 1);
      }
    }
    
  }
  
  // for(int i=0;i<n;i++) add_edge(i,ti, 1, 5000LL);

  ll ans=min_cost_flow(si,ti,tmp);

  
  for(int i=0;i<n;i++) add_edge(i,ti, 1, 0LL);

  

  for(int i=0;i<n;i++){
    if( i== root )continue;
    ll U=In[i]-Out[i];
    //    add_edge( i, parent[i], capmx , 1);
    //    add_edge( parent[i], i, capmx , 1);
    if( U  <= 0  ){
      //      add_edge( parent[i],i , -U+min(Size[i],sum%n)  , 1);
    }else{
      //      add_edge( i,parent[i] , U , 1);
      
      if( min(sum%n,Size[i])-U >0 ){
        add_edge( parent[i], i, min(sum%n,Size[i])-U , 1);
      }
    }
    
  }
  ans += min_cost_flow(si,ti,tmp );
  
  //ans -= 5000LL * (sum%n);

  cout<< ans <<endl;
  return 0;
}
accuracy: 1
time_ms: 1350
memory_kb: 4980
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned int uint;

int bar(uint x){
  if(x==0)return -1;
  return 31- __builtin_clz(x);
}
struct RadixHeapInt {
  uint v[33][5005];
  uint w[33];
  uint last,sz;
  
  RadixHeapInt() {
    memset( w , 0, sizeof(w) );
    last = sz = 0;
  }
  
  void push(uint x){
    sz++;
    v[ bar(x^last)+1 ][ w[ bar(x^last)+1 ] ]=x;
    w[ bar(x^last)+1 ]++;
  }
  
  uint pop(){
    if( !w[0] ){
      int i=1;
      while( !w[i] )i++;
      uint new_last =
        *min_element(v[i] , v[i]+w[i] );
      
      for(int j=0;j<(int)w[i];j++){
        uint x=v[i][j];
        v[ bar(x^new_last)+1 ][ w[bar(x^new_last)+1] ]=x;
        w[bar(x^new_last)+1]++;
      }
      last = new_last;
      w[i]=0;
    }
    sz--;
    w[0]--;
    return last;
  }
};

typedef long long ll;
const int MAX_V = 5005;

typedef pair< int , int > P;

const ll INF=1000000000LL;

const ll capmx=10000000000000LL;

struct edge { ll to,cap,cost,rev; };

int V;
vector<edge> G[MAX_V];
ll h[MAX_V];
int dist[MAX_V];
ll prevv[MAX_V],preve[MAX_V];

void add_edge(ll from,ll to,ll cap,ll cost, bool flag = false){
  G[from].push_back((edge){to,cap,cost,(ll)G[to].size()});
  if( flag )return;
  G[to].push_back((edge){from,0,-cost,(ll)G[from].size()-1});
}


RadixHeapInt que;

ll min_cost_flow(int s,int t,ll &f){
  ll mini = INF;
  ll res = 0;
  //fill(h,h+V,0);
  //  h[t]=0;
  //  cout<< f << ' ' <<h[t] <<endl;
  //  res -= f*h[t];
  
  while(f>0){
    que.last=0;
    memset( dist , 1 , sizeof( dist ) );
    dist[s]=0;
    que.push( s );
    while( que.sz ){
      uint key = que.pop();
      int v = key%MAX_V;
      int cost = key/MAX_V;
      if(dist[v]<cost)continue;
      if(v==t)continue;
      
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap>0&&dist[e.to] > dist[v]+e.cost+h[v]-h[e.to]){
          dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];

          mini  = min( mini , e.cost+h[v]-h[e.to] );
          prevv[e.to]=v;
          preve[e.to]=i;
          que.push(dist[e.to]*MAX_V+e.to);
        }
      }
    }
    if(dist[t]==dist[MAX_V-1]){
      break;
    }
    for(int v=0;v<V;v++){
      h[v]+=dist[v];
    }
    ll d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,(ll)G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    res+=(ll)d*h[t];
    for(int v=t;v!=s;v=prevv[v]){

      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      if( prevv[v] == s )break;
      G[v][e.rev].cap += d;
    }
  }
  //  cout<<mini<<endl;
  return res;
}




ll In[5000];
ll Out[5000];
ll Size[5000];
vector<int> g[5000];
int parent[5000];

void dfs(int pos,int prev){
  parent[pos]=prev;
  for(int i=0;i<(int)g[pos].size();i++){
    int to=g[pos][i];
    if(to==prev)continue;
    dfs(to,pos);
    In[pos]+=In[to];
    Out[pos]+=Out[to];
    Size[pos]+=Size[to];
  }
}


int main(){
  ll n, sum=0;
  ll x[5000];
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>x[i];
    sum+=x[i];
  }
  
  int si=n;
  int ti=n+1;
  
  V=ti+1;
  
  for(int i=0;i+1<n;i++){
    int u,v;
    cin>>u>>v;
    u--;
    v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }


  int root = rand() % n;
  
  ll tmp=sum;
  for(int i=0;i<n;i++){
    Size[i]=1;
    In[i]=Out[i]=0;
    
    ll p= min(sum/n , x[i]);
    tmp-=p;
    if(x[i]-p>0){
      add_edge(si,i,x[i]-p,0, true);
      In[i] = x[i]-p;
    }

    if( sum/n-p > 0 ){
      add_edge(i,ti, sum/n-p , 0 );
      Out[i] = (sum/n-p);
    }
  }
  
  dfs( root ,-1);
  

  for(int i=0;i<n;i++){
    if( i== root )continue;
    
    ll U=In[i]-Out[i];
    //    add_edge( i, parent[i], capmx , 1);
    //    add_edge( parent[i], i, capmx , 1);
    
    if( U  <= 0  ){
      add_edge( parent[i],i , -U+min(Size[i],sum%n)  , 1);
    }else{
      add_edge( i,parent[i] , U , 1);
      
      if( min(sum%n,Size[i])-U >0 ){
        add_edge( parent[i], i, min(sum%n,Size[i])-U , 1);
      }
    }
    
  }
  
  // for(int i=0;i<n;i++) add_edge(i,ti, 1, 5000LL);

  ll ans=min_cost_flow(si,ti,tmp);

  for(int i=0;i<n;i++) add_edge(i,ti, 1, 5000LL);
  ans += min_cost_flow(si,ti,tmp );
  
  ans -= 5000LL * (sum%n);

  cout<< ans <<endl;
  return 0;
}
accuracy: 1
time_ms: 2230
memory_kb: 5116
final_rank: 11