首页 > 其他分享 >CF1420D & gym102012 G

CF1420D & gym102012 G

时间:2022-10-11 15:11:36浏览次数:48  
标签:int res 线段 gym102012 CF1420D 端点 顶点 mod

CF1420D:

注意到任意条线段的交集如果非空的话必定是一条线段,且这条线段的左端点一定是某条线段的左端点。

很明显先将线段离散化,然后去枚举相交的线段的左端点。

我们设 \(p\) 是覆盖了某个位置的线段的数量,\(s\) 是以这个位置为左端点的线段数量。由于我们选出的这 \(k\) 条线段中至少要有一条以这个位置为左端点,所以容斥一下得到这个位置的答案为
\(\binom{p}{k}-\binom{p-s}{k}\)。

具体细节看代码。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 300005, M = 600005, mod = 998244353;
int n, k;
int fac[N], inv[N];
int l[N], r[N], _[M], tot;
int cntL[M], cntR[M];

int qpow(int x, int y) {
	int res = 1;
	while (y) {
		if (y & 1) res = 1ll * res * x % mod;
		x = 1ll * x * x % mod;
		y >>= 1;
	}
	return res;
}

void init(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
	inv[n] = qpow(fac[n], mod - 2);
	for (int i = n - 1; ~i; --i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}

int C(int n, int m) {
	if (n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * inv[n - m] % mod * inv[m] % mod;
}

int main() {
	scanf("%d%d", &n, &k), init(n);
	for (int i = 1; i <= n; ++i) scanf("%d%d", &l[i], &r[i]), _[++tot] = l[i], _[++tot] = r[i];
	sort(_ + 1, _ + tot + 1), tot = unique(_ + 1, _ + tot + 1) - (_ + 1);
	for (int i = 1; i <= n; ++i) {
		l[i] = lower_bound(_ + 1, _ + tot + 1, l[i]) - _, r[i] = lower_bound(_ + 1, _ + tot + 1, r[i]) - _;
		++cntL[l[i]], ++cntR[r[i] + 1];
	}
	int sum = 0, ans = 0;
	for (int i = 1; i <= tot; ++i) {
		sum += cntL[i] - cntR[i];
		ans = (ans + (C(sum, k) - C(sum - cntL[i], k) + mod) % mod) % mod;
	}
	printf("%d", ans);
	return 0;
}

CF gym102012 G:

把序列搬到了树上。

重点在于怎么不重不漏的统计答案。

下文称顶点为一条路径的两个端点的 LCA。

注意到如果两条路径有公共点,那么其中必有一个点是某条路径的顶点

所以想到枚举每个点,计算至少有一条路径的顶点是该点的方案数。

简单说明一下,因为对于一个点 \(x\),和一条经过它的路径 \(L\),必有 \(L\) 的顶点不是 \(x\) 就是 \(x\) 的祖先,不可能是 \(x\) 的后代。也就是说 \(x\) 是这个选法中深度最深的顶点。而一个选法不可能有两个不同的深度最深的顶点(否则这两个顶点对应的路径就没有公共点了),所以这个对应方法是唯一的了。

具体细节看代码。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 300005, mod = 1e9 + 7;
int T;
int n, t, m, k;
int head[N], ver[N*2], nxt[N*2], cnt;
int fac[N], inv[N];
int fa[N][20], dep[N];
int num[N], a[N];

void add(int u, int v) {
	ver[++cnt] = v, nxt[cnt] = head[u], head[u] = cnt;
}

int qpow(int x, int y) {
	int res = 1;
	while (y) {
		if (y & 1) res = 1ll * res * x % mod;
		x = 1ll * x * x % mod;
		y >>= 1;
	}
	return res;
}

void init(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
	inv[n] = qpow(fac[n], mod - 2);
	for (int i = n - 1; ~i; --i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}

int C(int n, int m) {
	if (n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * inv[n - m] % mod * inv[m] % mod;
}

void dfs(int u, int Fa) {
	for (int i = head[u]; i; i = nxt[i]) {
		int v = ver[i];
		if (v == Fa) continue;
		dep[v] = dep[u] + 1, fa[v][0] = u;
		for (int j = 1; j <= t; ++j)
			fa[v][j] = fa[fa[v][j - 1]][j - 1];
		dfs(v, u);
	}
}

void dfs1(int u, int Fa) {
	for (int i = head[u]; i; i = nxt[i]) {
		int v = ver[i];
		if (v == Fa) continue;
		dfs1(v, u), a[u] += a[v];
	}
}

int LCA(int x, int y) {
	if (dep[x] > dep[y]) swap(x, y);
	for (int i = t; ~i; --i)
		if (dep[x] <= dep[fa[y][i]]) y = fa[y][i];
	if (x == y) return x;
	for (int i = t; ~i; --i)
		if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
	return fa[x][0];
}

void solve() {
	scanf("%d%d%d", &n, &m, &k), t = (log(n) / log(2)) + 1;
	memset(head + 1, 0, sizeof (int) * n), cnt = 0;
	memset(num + 1, 0, sizeof (int) * n);
	memset(a + 1, 0, sizeof (int) * n);
	for (int i = 1, u, v; i < n; ++i) scanf("%d%d", &u, &v), add(u, v), add(v, u);
	dep[1] = 1, dfs(1, 0);
	for (int i = 1, x, y; i <= m; ++i) {
		scanf("%d%d", &x, &y); int z = LCA(x, y);
		++num[z]; ++a[x], ++a[y], --a[z], --a[fa[z][0]];
	}
	dfs1(1, 0);
	int ans = 0;
	for (int i = 1; i <= n; ++i) ans = (ans + (C(a[i], k) - C(a[i] - num[i], k) + mod) % mod) % mod;
	printf("%d\n", ans);
}

int main() {
	init(300000);
	scanf("%d", &T);
	while (T--) solve();
	return 0;
}

标签:int,res,线段,gym102012,CF1420D,端点,顶点,mod
From: https://www.cnblogs.com/Kobe303/p/16779253.html

相关文章