0228模擬賽

T1

在這裏插入圖片描述
在這裏插入圖片描述

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 4505;
const int mod = 998244853;
int n, a[MAXN], nxt[MAXN], sz[MAXN], f[MAXN][MAXN], sum[MAXN];
int main() {
	freopen("administration.in","r",stdin);
	freopen("administration.out","w",stdout);
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
	a[1] = n;
	for(int i = n; i >= 1; --i) {
		if((a[i]=a[i]+i-1) > n) { puts("0"); return 0; }
		nxt[i] = i; sz[i] = 1; f[i][1] = 1;
		a[i] = a[nxt[a[i]]];
		for(int j = i+1; j <= a[i]; j = a[nxt[j]]+1) {
			sum[sz[i]+1] = 0;
			for(int k = sz[i]; k >= 0; --k)
				sum[k] = (sum[k+1] + f[i][k]) % mod, f[i][k] = 0;
			for(int k = 1; k <= sz[i]; ++k)
				for(int l = 1; l <= sz[j]; ++l)
					f[i][k+l] = (f[i][k+l] + 1ll * f[j][l] * sum[k]) % mod;
			sz[i] += sz[j];
		}
		for(int j = i; j <= a[i]; ++j) nxt[j] = i;
	}
	int ans = 0;
	for(int i = 1; i <= n; ++i) ans = (ans + f[1][i]) % mod;
	printf("%d\n", ans);
}

T2

在這裏插入圖片描述
在這裏插入圖片描述

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5005;
int n, s[MAXN], S[MAXN], w[MAXN], cnt[MAXN], aw;
int ml[MAXN], mr[MAXN], sl[MAXN], sr[MAXN];
int main () {
	freopen("exploration.in", "r", stdin);
	freopen("exploration.out", "w", stdout);
	int T; scanf("%d", &T); while(T--) {
		scanf("%d", &n); aw = 0;
		for(int i = 1; i <= n; ++i)
			scanf("%d", &s[i]), S[i] = S[i-1] + s[i];
		s[0] = s[n+1] = 5000;
		for(int i = 1; i <= n; ++i)
			scanf("%d", &w[i]), aw += w[i];
		int lp, rp;
	
		for(int i = 1; i <= n; ++i) if(w[i]) { lp = i; break; }
		ml[lp] = s[lp]; sl[lp] = 0;
		for(int i = lp+1; i <= n+1; ++i) ml[i] = min(ml[i-1], s[i]);
		for(int i = lp+1; i <= n+1; ++i) sl[i] = sl[i-1]+(s[i]-ml[i]);
		
		for(int i = n; i >= 1; --i) if(w[i]) { rp = i; break; }
		mr[rp] = s[rp]; sr[rp] = 0;
		for(int i = rp-1; i >= 0; --i) mr[i] = min(mr[i+1], s[i]);
		for(int i = rp-1; i >= 0; --i) sr[i] = sr[i+1]+(s[i]-mr[i]);
		
		double ans = 1e18;
		for(int l = 1; l <= n; ++l) {
			memset(cnt, 0, sizeof cnt);
			int h = 1000, base = 0, cw = 0;
			for(int r = l; r <= n; ++r) {
				if(s[r] <= h) {
					base += h-s[r], ++cnt[s[r]], ++cw;
					while(base > aw) base -= cw -= cnt[h--];
				}
				double res = 0;
				int lh = s[l-1], rh = s[r+1];
				if(lp < l) res += sl[l], lh = ml[l-1];
				if(rp > r) res += sr[r], rh = mr[r+1];
				double x = h + 1.0*(aw-base)/cw;
				res += (S[r]-S[l-1]) - (r-l+1)*x + aw;
				if(x > min(lh, rh))
					res += (x-min(lh, rh)) * (r-l+1);
				ans = min(ans, res);
			}
		}
		printf("%.5f\n", ans);
	}
}

T3

在這裏插入圖片描述
費用流直接做。
原題:CF1061E

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef long long LL;
const int MAXP = 1010;
const int MAXN = 505;
const int MAXM = 5005;
const int INF = 0x3f3f3f3f;
int n, a[MAXN], rt[2], q[2], fa[2][MAXN], lim[2][MAXN];
vector<int>G[2][MAXN];

int S, T, ans, cl[2][MAXN]; bool flg[2][MAXN];

int dfs(int o, int u, int now) {
	if(flg[o][u]) now = u;
	cl[o][u] = now;
	int siz = G[o][u].size(), v, sum = 0;
	for(int i = 0; i < siz; ++i)
		if((v=G[o][u][i]) != fa[o][u]) {
			fa[o][v] = u;
			sum += dfs(o, v, now);
		}
	int re = flg[o][u] ? lim[o][u] : sum;
	if(flg[o][u]) lim[o][u] -= sum;
	return re;
}


int info[MAXP], fir[MAXP], to[MAXM], nxt[MAXM], c[MAXM], w[MAXM], cnt=1;
inline void link(int u, int v, int cc, int ww) {
	to[++cnt] = v, nxt[cnt] = fir[u], fir[u] = cnt; c[cnt] = cc, w[cnt] = ww;
	to[++cnt] = u, nxt[cnt] = fir[v], fir[v] = cnt; c[cnt] = 0, w[cnt] = -ww;
}
int dis[MAXP];
bool inq[MAXP];
inline bool spfa() {
	static queue<int> q;
	memset(dis, 0x3f, sizeof dis);
	dis[S] = 0; q.push(S);
	while(!q.empty()) {
		int u = q.front(); q.pop(); inq[u] = 0;
		for(int i = fir[u], v; i; i = nxt[i])
			if(c[i] && dis[v=to[i]] > dis[u] + w[i]) {
				dis[v] = dis[u] + w[i];
				if(!inq[v]) inq[v] = 1, q.push(v);
			}
	}
	return dis[T] < INF;
}

bool vis[MAXP];

int Aug(int u, int Max) {
	if(u == T) { ans += Max * dis[T]; return Max; }
	vis[u] = 1;
	int delta, flow = 0;
	for(int &i = info[u], v; i; i = nxt[i])
		if(c[i] && dis[v=to[i]] == dis[u] + w[i] && !vis[v] && (delta=Aug(v, min(Max-flow, c[i])))) {
			flow += delta, c[i] -= delta, c[i^1] += delta;
			if(flow == Max) break;
		}
	vis[u] = 0; return flow;
}
int Flow;
inline void Max_Cost_flow(int s, int t) {
	S = s, T = t;
	while(spfa())
		memcpy(info, fir, sizeof fir), Flow += Aug(S, INF);
}
int main () {
	freopen("negotiation.in", "r", stdin);
	freopen("negotiation.out", "w", stdout);
	scanf("%d%d%d", &n, &rt[0], &rt[1]);
	for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
	for(int o = 0; o < 2; ++o)
		for(int i = 1, x, y; i < n; ++i)
			scanf("%d%d", &x, &y), G[o][x].pb(y), G[o][y].pb(x);
	for(int o = 0; o < 2; ++o) {
		scanf("%d", &q[o]);
		for(int i = 1, x, y; i <= q[o]; ++i)
			scanf("%d%d", &x, &y), lim[o][x] = y, flg[o][x] = 1;
	}
	dfs(0, rt[0], rt[0]), dfs(1, rt[1], rt[1]);
	for(int i = 1; i <= n; ++i)
		if(lim[0][i] < 0 || lim[1][i] < 0) { puts("-1"); return 0; }
	int S = 0, T = (n<<1)+1, s1 = 0, s2 = 0;
	for(int i = 1; i <= n; ++i) {
		if(lim[0][i]) link(S, i, lim[0][i], 0), s1 += lim[0][i];
		if(lim[1][i]) link(i+n, T, lim[1][i], 0), s2 += lim[1][i];
	}
	for(int i = 1; i <= n; ++i) link(cl[0][i], n+cl[1][i], 1, -a[i]);
	if(s1 != s2) { puts("-1"); return 0; }
	Max_Cost_flow(S, T);
	if(s1 != Flow) { puts("-1"); return 0; }
	printf("%d\n", -ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章