SDOI/SXOI2022 做题笔记

SDOI/SXOI2022 做题笔记

持续更新中……

题目:https://www.luogu.com.cn/problem/list?tag=114%7C59&page=1

[SDOI/SXOI2022] 小 N 的独立集

时间复杂度 \(O(n^2k^4)\)

ケロシの代码
const int N = 1e3 + 5;
const int P = 1e9 + 7;
inline int add(int x, int y) { return (x + y < P ? x + y : x + y - P); }
inline void Add(int & x, int y) { x = (x + y < P ? x + y : x + y - P); }
inline int sub(int x, int y) { return (x < y ? x - y + P : x - y); }
inline void Sub(int & x, int y) { x = (x < y ? x - y + P : x - y); }
inline int mul(int x, int y) { return (1ll * x * y) % P; }
inline void Mul(int & x, int y) { x = (1ll * x * y) % P; }
int fp(int x, int y) {
	int res = 1;
	for(; y; y >>= 1) {
		if(y & 1) Mul(res, x);
		Mul(x, x);
	}
	return res;
}
int n, k;
int fi[N], ne[N << 1], to[N << 1], ecnt;
int sz[N], dp[N][N * 5][6], f[N * 5][6], ans[N * 5];
void add_edge(int u, int v) {
	ne[++ ecnt] = fi[u];
	to[ecnt] = v;
	fi[u] = ecnt;
}
void dfs(int u, int fa) {
	sz[u] = 1;
	FOR(i, 1, k) dp[u][0][i] = 1;
	for(int i = fi[u]; i; i = ne[i]) {
		int v = to[i];
		if(v == fa) continue;
		dfs(v, u);
		FOR(i, 0, (sz[u] + sz[v]) * k) FOR(j, 0, 5) f[i][j] = 0;
		FOR(i, 0, sz[u] * k) FOR(j, 0, 5) if(dp[u][i][j])
			FOR(p, 0, sz[v] * k) FOR(q, 0, 5) if(dp[v][p][q])
				Add(f[i + p + q][max(i + p + q, i + j + p) - (i + p + q)], mul(dp[u][i][j], dp[v][p][q]));
		FOR(i, 0, (sz[u] + sz[v]) * k) FOR(j, 0, 5) dp[u][i][j] = f[i][j];
		sz[u] += sz[v];
	}
}
void solve() {
	cin >> n >> k;
	REP(_, n - 1) {
		int u, v;
		cin >> u >> v;
		add_edge(u, v); 
		add_edge(v, u);
	}
	dfs(1, 0);
	FOR(i, 1, n * k) FOR(j, 0, 5) Add(ans[i + j], dp[1][i][j]); 
	FOR(i, 1, n * k) cout << ans[i] << endl;
}

[SDOI/SXOI2022] 整数序列

ケロシの代码
const int N = 3e5 + 5;
const int B = 300;
const ll LNF = 1e18 + 128;
int n, q, a[N], b[N];
vector<int> e[N];
vector<PII> qs[N];
int p[N], len, c[N];
ll s[N], f[N << 1];
ll ans[N << 2];
void solve() {
	cin >> n >> q;
	FOR(i, 1, n) cin >> a[i];
	FOR(i, 1, n) cin >> b[i];
	FOR(i, 1, n) e[a[i]].push_back(i);
	map<PII, ll> mp;
	memset(f, 0x3f, sizeof f);
	FOR(i, 1, q) {
		int x, y;
		cin >> x >> y;
		if(SZ(e[x]) < SZ(e[y])) swap(x, y);
		if((SZ(e[x]) > B && SZ(e[y]) > B) || (SZ(e[x]) <= B && SZ(e[y]) <= B)) {
			if(mp.count({x, y})) {
				ans[i] = mp[{x, y}];
				continue;
			}
			int p1 = 0, p2 = 0; len = 0;
			while(p1 < SZ(e[x]) || p2 < SZ(e[y])) {
				if(p2 == SZ(e[y]) || (p1 < SZ(e[x]) && e[x][p1] < e[y][p2])) {
					p[++ len] = e[x][p1];
					p1 ++;
				}
				else {
					p[++ len] = e[y][p2];
					p2 ++;
				}
			}
			FOR(j, 1, len) c[j] = c[j - 1] + (a[p[j]] == x ? 1 : - 1);
			FOR(j, 1, len) s[j] = s[j - 1] + b[p[j]];
			ll res = - LNF;
			FOR(j, 0, len) {
				chmax(res, s[j] - f[N + c[j]]);
				chmin(f[N + c[j]], s[j]);
			}
			FOR(j, 0, len) f[N + c[j]] = LNF;
			ans[i] = mp[{x, y}] = res;
		}
		else {
			qs[x].push_back({y, i});
		}
	}
	FOR(x, 1, n) if(! qs[x].empty()) {
		set<int> S(ALL(e[x]));
		FOR(i, 1, n) c[i] = c[i - 1] + (a[i] == x);
		FOR(i, 1, n) s[i] = s[i - 1] + (a[i] == x ? b[i] : 0);
		for(auto h : qs[x]) {
			int y = FI(h);
			vector<int> ex;
			for(int pos : e[y]) {
				auto it = S.lower_bound(pos);
				if(it != S.end()) {
					ex.push_back(* it);
					S.erase(it);
				}
				it = S.lower_bound(pos);
				if(it != S.begin()) {
					it = prev(it);
					ex.push_back(* it);
					S.erase(it);
				}
				it = S.lower_bound(pos);
				if(it != S.begin()) {
					it = prev(it);
					ex.push_back(* it);
					S.erase(it);
				}
			}
			sort(ALL(ex));
			int p1 = 0, p2 = 0; len = 0;
			while(p1 < SZ(ex) || p2 < SZ(e[y])) {
				if(p2 == SZ(e[y]) || (p1 < SZ(ex) && ex[p1] < e[y][p2])) {
					p[++ len] = ex[p1];
					p1 ++;
				}
				else {
					p[++ len] = e[y][p2];
					p2 ++;
				}
			}
			int cnt = 0; ll sum = 0;
			ll res = - LNF;
			FOR(i, 0, len) {
				if(a[p[i]] == y) cnt --, sum += b[p[i]];
				chmax(res, s[p[i]] + sum - f[N + c[p[i]] + cnt]);
				chmin(f[N + c[p[i]] + cnt], s[p[i]] + sum);
			}
			ans[SE(h)] = res;
			cnt = 0; sum = 0;
			FOR(i, 0, len) {
				if(a[p[i]] == y) cnt --, sum += b[p[i]];
				f[N + c[p[i]] + cnt] = LNF;
			}
			for(int pos : ex) S.insert(pos);
		}
	}
	FOR(i, 1, q) cout << ans[i] << endl;
}
posted @ 2024-12-24 20:01  KevinLikesCoding  阅读(1)  评论(0编辑  收藏  举报