2025-1-6 / 2025-1-7 做题笔记

2025-1-6 / 2025-1-7 做题笔记

持续更新中……

P11365 [Ynoi2024] 新本格魔法少女りすか

ケロシの代码
namespace IO {
	char buf[1024], * p1 = buf, * p2 = buf;
	inline char gc() {
		if(p1 == p2) {
			p2 = buf + fread(buf, 1, sizeof buf, stdin);
			p1 = buf;
		}
		return p1 == p2 ? EOF : * p1 ++;
	}
	int read() {
		int res = 0;
		char c = gc();
		while(c < '0' || c > '9') {
			c = gc();
		}
		while('0' <= c && c <= '9') {
			res = (res << 3) + (res << 1) + (c ^ 48);
			c = gc();
		}
		return res;
	}
}
using IO :: read;
const int N = 5e5 + 5;
const int B = 409;
const int M = (N >> 6) + 3;
const int SN = N / B + 5;
int n, m, a[N];
int sn, st[SN], ed[SN], p[N];
int c[N];
ll s[N], ans[N];
vector<PII> e[N];
bitset<N> b[SN];
void build() {
	for(int l = 1, r = B; l <= n; l += B, r += B) {
		sn ++;
		st[sn] = l;
		ed[sn] = min(r, n);
	}
	FOR(i, 1, sn) {
		FOR(j, st[i], ed[i]) {
			p[j] = i;
		}
	}
}
struct fenwick {
	ull b[M]; int c[M]; 
	void init() {
		memset(b, 0, sizeof b);
		memset(c, 0, sizeof c);
	}
	inline int lowbit(int x) {
		return - x & x;
	}
	inline void modify(int u) {
		b[u >> 6] |= (1ull << (u & 63));
		for(int i = (u >> 6) + 1; i < M; i += lowbit(i))
			c[i] ++;
	}
	inline void clear(int u) {
		b[u >> 6] = 0;
		for(int i = (u >> 6) + 1; i < M && c[i]; i += lowbit(i)) 
			c[i] = 0;
	}
	inline int query(int u) {
		u ++;
		int res = __builtin_popcountll(b[u >> 6] & ((1ull << (u & 63)) - 1));
		for(int i = u >> 6; i; i -= lowbit(i))
			res += c[i];
		return res;
	}
} t;
void solve() {
	n = read(); m = read();
	FOR(i, 1, n) a[i] = read();
	build();
	FOR(i, 1, m) {
		int k; k = read();
		REP(_, k) {
			int l, r;
			l = read(); r = read();
			if(k == 1) break;
			e[i].push_back({l, r});
			int pl = p[l], pr = p[r];
			FOR(j, pl + 1, pr - 1) 
				b[j][i] = 1;
		}
	}
	FOR(i, 1, sn) if(b[i].count()) {
		memset(c, 0, sizeof c);
		FOR(j, st[i], ed[i]) c[a[j]] ++;
		FOR(j, 1, n) c[j] += c[j - 1];
		FOR(j, 1, st[i] - 1) s[j] = c[n] - c[a[j]];
		FOR(j, st[i], ed[i]) s[j] = 0;
		FOR(j, ed[i] + 1, n) s[j] = c[a[j] - 1];
		FOR(j, 1, n - 1) s[j + 1] += s[j];
		FOR(j, 1, m) if(b[i][j]) {
			int k = 0;
			for(; k < SZ(e[j]); k ++) {
				int l, r; tie(l, r) = e[j][k];
				if(r >= st[i]) break;
				ans[j] += s[r] - s[l - 1];
			}
			for(k ++; k < SZ(e[j]); k ++) {
				int l, r; tie(l, r) = e[j][k];
				if(l > ed[i]) break;
			}
			for(; k < SZ(e[j]); k ++) {
				int l, r; tie(l, r) = e[j][k];
				int pl = p[l], pr = p[r];
				if(pl == pr) {
					ans[j] += s[r] - s[l - 1];
				}
				else {
					ans[j] += s[ed[pl]] - s[l - 1];
					ans[j] += s[r] - s[st[pr] - 1];
				}
			}
		}
	}
	FOR(i, 1, m) {
		int cnt = 0;
		for(auto h : e[i]) {
			int l, r; tie(l, r) = h;
			int pl = p[l], pr = p[r];
			if(pl == pr) {
				FOR(j, l, r) ans[i] += t.query(a[j]);
				FOR(j, l, r) t.modify(a[j]), cnt ++;
			}
			else {
				FOR(j, l, ed[pl]) ans[i] += t.query(a[j]);
				FOR(j, st[pr], r) ans[i] += t.query(a[j]);
				FOR(j, l, ed[pl]) t.modify(a[j]), cnt ++;
				FOR(j, st[pr], r) t.modify(a[j]), cnt ++;
			}
		}
		if(cnt > 2500) {
			t.init();
			continue;
		}
		for(auto h : e[i]) {
			int l, r; tie(l, r) = h;
			int pl = p[l], pr = p[r];
			if(pl == pr) {
				FOR(j, l, r) t.clear(a[j]);
			}
			else {
				FOR(j, l, ed[pl]) t.clear(a[j]);
				FOR(j, st[pr], r) t.clear(a[j]);
			}
		}
	}
	FOR(i, 1, m) cout << ans[i] << endl;
}

CF1693D - Decinc Dividing

ケロシの代码
const int N = 2e5 + 5;
const int INF = 1e9 + 7;
int n, a[N], f[N], g[N];
void solve() {
	cin >> n;
	FOR(i, 1, n) cin >> a[i];
	ll ans = 0;
	int lst = n;
	FOR(i, 1, n) f[i] = INF, g[i] = - INF;
	ROF(l, n, 1) {
		f[l] = - INF; g[l] = INF;
		FOR(r, l + 1, n) {
			int F = INF, G = - INF;
			if(a[r - 1] > a[r]) chmin(F, f[r - 1]);
			if(g[r - 1] > a[r]) chmin(F, a[r - 1]);
			if(a[r - 1] < a[r]) chmax(G, g[r - 1]);
			if(f[r - 1] < a[r]) chmax(G, a[r - 1]);
			if(F == INF && G == - INF) {
				lst = r - 1;
				break;
			}
			if(F == f[r] && G == g[r]) break;
			f[r] = F, g[r] = G;
		} 
		ans += lst - l + 1;
	}
	cout << ans << endl;
}

AT UTPC2023G - Graph Weighting

ケロシの代码
const int N = 1e5 + 5;
const int M = 4e5 + 5;
const ll LNF = 1e18;
int n, m, k, V;
int fi[N], ne[M], to[M], ecnt;
int dfn[N], low[N], cnt;
int vis[N], dct;
PII dcc[N];
vector<int> e[N];
ll dp[N], f[N], g[N];
int p[N];
struct Node {
	int b, x;
	bool operator > (const Node & A) const {
		return 1ll * b * (x * 2 + 1) > 1ll * A.b * (A.x * 2 + 1);
	}
};
void add(int u, int v) {
	ne[++ ecnt] = fi[u];
	to[ecnt] = v;
	fi[u] = ecnt;
}
void tarjan(int u) {
	dfn[u] = low[u] = ++ cnt;
	for(int i = fi[u]; i; i = ne[i]) {
		int v = to[i];
		if(! dfn[v]) {
			tarjan(v);
			chmin(low[u], low[v]);
		}
		else {
			chmin(low[u], dfn[v]);
		}
	}
}
void dfs(int u, int dc) {
	vis[u] = 1;
	FI(dcc[dc]) ++;
	for(int i = fi[u]; i; i = ne[i]) {
		int v = to[i];
		if(vis[v] == 0) {
			if(low[v] >= dfn[u]) {
				dct ++;
				FI(dcc[dct]) ++;
				dfs(v, dct);
			}
			else {
				dfs(v, dc);
			}
		} 
		else if(vis[v] == 1) {
			SE(dcc[dc]) ++;
		}
	}
	vis[u] = 2;
}
void slv(int l, int r, int pl, int pr) {
	if(l > r) return;
	int mid = l + r >> 1;
	int pos = pl;
	FOR(i, pl, min(pr, mid))
		if(f[i] + g[mid - i] <= f[pos] + g[mid - pos])
			pos = i;
	p[mid] = pos;
	slv(l, mid - 1, pl, pos);
	slv(mid + 1, r, pos, pr);
}
void solve() {
	cin >> n >> m >> k >> V;
	REP(_, m) {
		int u, v;
		cin >> u >> v;
		add(u, v); add(v, u);
	}
	tarjan(1); dfs(1, 0);
	FOR(i, 1, dct) e[FI(dcc[i])].push_back(SE(dcc[i]));
	FOR(i, 1, k) dp[i] = LNF;
	dp[0] = 0;
	FOR(i, 2, n) if(! e[i].empty()) {
		FOR(j, 1, k / (i - 1)) g[j] = LNF;
		g[0] = 0;
		priority_queue<Node, vector<Node>, greater<Node>> pq;
		for(int b : e[i]) pq.push({b, 0});
		FOR(j, 1, k / (i - 1)) {
			if(pq.empty()) break;
			auto h = pq.top();
			pq.pop();
			g[j] = g[j - 1] + 1ll * h.b * (h.x * 2 + 1);
			if(h.x < V - 1) pq.push({h.b, h.x + 1});
		}
		REP(j, i - 1) {
			int len = 0;
			for(int l = j; l <= k; l += i - 1)
				f[++ len] = dp[l];
			slv(1, len, 1, len);
			ROF(l, len, 1) 
				chmin(dp[(l - 1) * (i - 1) + j], dp[(p[l] - 1) * (i - 1) + j] + g[l - p[l]]); 
		}
	}
	FOR(i, 0, k) cout << (dp[i] >= LNF ? - 1 : dp[i]) << " "; cout << endl;
}

ABC269Ex - Antichain

ケロシの代码
const int N = 2e5 + 5;
const int P = 998244353;
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 r[N << 2], a[N << 2], b[N << 2];
void NTT(int * a, int lim, int o) {
	REP(i, lim) if(i < r[i]) swap(a[i], a[r[i]]);
	for(int i = 1; i < lim; i <<= 1) {
		int wn = fp(o == 1 ? 3 : (P + 1) / 3, (P - 1) / (i << 1));
		for(int j = 0; j < lim; j += (i << 1)) {
			for(int k = 0, w = 1; k < i; k ++, Mul(w, wn)) {
				int x = a[j + k];
				int y = mul(a[j + k + i], w);
				a[j + k] = add(x, y);
				a[j + k + i] = sub(x, y);
			}
		}
	}
	if(o == 1) return;
	int inv = fp(lim, P - 2);
	REP(i, lim) Mul(a[i], inv);
}
VI conv(VI A, VI B) {
	int n = SZ(A), m = SZ(B);
	int lim = 1, l = 0;
	while(lim < n + m) lim <<= 1, l ++;
	REP(i, lim) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
	REP(i, lim) a[i] = b[i] = 0;
	REP(i, n) a[i] = A[i];
	REP(i, m) b[i] = B[i];
	NTT(a, lim, 1);
	NTT(b, lim, 1);
	REP(i, lim) Mul(a[i], b[i]);
	NTT(a, lim, - 1);
	VI C(n + m - 1);
	REP(i, n + m - 1) C[i] = a[i];
	return C;
}
VI add(VI A, VI B) {
	int n = SZ(A), m = SZ(B);
	VI C(max(n, m));
	REP(i, n) Add(C[i], A[i]);
	REP(i, m) Add(C[i], B[i]);
	return C;
}
int n, p[N];
int fi[N], ne[N], to[N], ecnt;
int sz[N], son[N];
int dfn[N], rnk[N], top[N], til[N], cnt;
VI F[N], A[N]; int len;
void add_edge(int u, int v) {
	ne[++ ecnt] = fi[u];
	to[ecnt] = v;
	fi[u] = ecnt;
}
void dfs1(int u) {
	sz[u] = 1;
	son[u] = - 1;
	for(int i = fi[u]; i; i = ne[i]) {
		int v = to[i];
		dfs1(v);
		sz[u] += sz[v];
		if(son[u] == - 1 || sz[son[u]] < sz[v]) son[u] = v;
	}
}
void dfs2(int u, int tp) {
	dfn[u] = ++ cnt;
	rnk[cnt] = u;
	top[u] = tp;
	til[tp] = u;
	if(son[u] != - 1) dfs2(son[u], tp);
	for(int i = fi[u]; i; i = ne[i]) {
		int v = to[i];
		if(v == son[u]) continue;
		dfs2(v, v);
	}
}
VI prod(int l, int r) {
	if(l > r) return {1};
	if(l == r) {
		return A[l];
	}
	int mid = l + r >> 1;
	return conv(prod(l, mid), prod(mid + 1, r));
}
pair<VI, VI> slv(int l, int r) {
	if(l == r) {
		int u = rnk[l]; len = 0;
		for(int i = fi[u]; i; i = ne[i]) {
			int v = to[i];
			if(v == son[u]) continue;
			A[++ len] = F[v];
		}
		return {prod(1, len), {1}};
	}
	int mid = l + r >> 1;
	auto L = slv(l, mid);
	auto R = slv(mid + 1, r);
	return {
		conv(FI(L), FI(R)), 
		add(SE(L), conv(FI(L), SE(R)))
	};
}
void solve() {
	cin >> n;
	FOR(i, 2, n) cin >> p[i];
	FOR(i, 2, n) add_edge(p[i], i);
	dfs1(1); dfs2(1, 1);
	ROF(u, n, 1) if(top[u] == u) {
		auto h = slv(dfn[u], dfn[til[u]]);
		SE(h).insert(SE(h).begin(), 0);
		int v = dfn[p[u]];
		F[u] = add(FI(h), SE(h));
	}
	F[1].resize(n + 1);
	FOR(i, 1, n) cout << F[1][i] << endl;
}
posted @   KevinLikesCoding  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示