20200926

T1 T2 都不想说,太傻比了, 是个人就会。

T3

对于没加入一条边如果连得两个点不在同一个联通块中并查集链接,记录练了多少条边
最后的时候用n-1减去连了多少条边,就是需要再连几条边。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define N 100010
#define M 1010

using namespace std;
int n, m, cnt;
int fath[N];

int read() {
	int s = 0, f = 0; char ch = getchar();
	while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}

int father(int x) {
	if (x != fath[x]) fath[x] = father(fath[x]);
	return fath[x];
}

int main() {
	n = read(), m = read();
	for (int i = 1; i <= n; i++) fath[i] = i;
	for (int i = 1, x, y; i <= m; i++) {
		x = read(), y = read();
		int fx = father(x), fy = father(y);
		if (fx != fy) {
			cnt++;
			fath[fx] = fy;
		}
	}
	n--;
	if (cnt == n) puts("0");
	else cout << n - cnt << "\n";
}

T4

好妙
首先你可以写出一个人人都会的 \(n^2\) dp式子,长这个样子。

\[dp_i = \max (dp_i, dp_j + 1) \]

for (int i = 1; i <= n; i++) 
	for (int j = 1; j <= i - 1; j++)
		if (abs(a[i] - a[j]) <= k) dp[i] = max(dp[i], dp[j] + 1);

上边这个需要 \(n^2\) 解决,考虑将内层循环优化掉。

考虑线段树维护a值域,线段树中存 dp 值,我们可以每次找 \([a_i-k, a_i+k]\) 区间内的最大值,然后将这个最大值插入 \(a_i\) 中,同时我们记录当前的 dp 值。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define lson rt << 1
#define rson rt << 1 | 1
#define N 300010
#define M 1010

using namespace std;
int n, k, a[N], dp[N];
struct node {
	int sum;
}tree[N << 2];

int read() {
	int s = 0, f = 0; char ch = getchar();
	while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}

void push_up(int rt) {
	tree[rt].sum = max(tree[lson].sum, tree[rson].sum);
}

void build(int rt, int l, int r) {
	tree[rt].sum = 0;
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(lson, l, mid), build(rson, mid + 1, r);
	push_up(rt);
}

void change(int rt, int c, int l, int r, int pos) {
	if (l == r) {
		tree[rt].sum = c;
		return;
	}
	int mid = (l + r) >> 1;
	if (pos <= mid) change(lson, c, l, mid, pos);
	else change(rson, c, mid + 1, r, pos);
	push_up(rt);
}

int query(int rt, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[rt].sum;
	int mid = (l + r) >> 1, ans = 0;
	if (L <= mid) ans = max(ans, query(lson, l, mid, L, R));
	if (R > mid) ans = max(ans, query(rson, mid + 1, r, L, R));
	return ans;
}

int main() {
	n = read(), k = read();
	int m = 0;
	for (int i = 1; i <= n; i++) a[i] = read(), m = max(a[i] + 1, m);
	build(1, 1, m);
	for (int i = 1; i <= n; i++) {
		dp[i] = query(1, 1, m, max(a[i] - k, 1), min(a[i] + k, m)) + 1;
		change(1, dp[i], 1, m, a[i]);
	}
	int ans = 0;
	for (int i = 1; i <= n; i++) ans = max(ans, dp[i]);
	cout << ans << "\n";
}

T5

可以线段树解决

上传的时候就是

void push_up(int rt) {
	tree[rt].sum = ((tree[lson].sum * q_pow(10, tree[rson].len)) % mod + tree[rson].sum) % mod;
}

应该很好理解。

我们发现 \(77777777 = (10^8 - 1) \times \frac{7}{9}\)

然后我们可以根据这个东西搞一搞懒标记下放和修改操作。

预处理 9 在 \(\text{mod}\) 998244353 的逆元即可。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define lson rt << 1
#define rson rt << 1 | 1
#define N 200010
#define M 1010

using namespace std;
const int mod = 998244353;
const int inv = 443664157;
int n, m;
struct node {
	ll sum, len, lazy;
}tree[N << 2];

int read() {
	int s = 0, f = 0; char ch = getchar();
	while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}

ll q_pow(ll a, ll b) {
	ll ans = 1;
	while (b) {
		if (b & 1) ans = (ans * a) % mod;
		a = (a * a) % mod;
		b >>= 1; 
	}
	return ans;
}

void push_up(int rt) {
	tree[rt].sum = ((tree[lson].sum * q_pow(10, tree[rson].len)) % mod + tree[rson].sum) % mod;
}

void build(int rt, int l, int r) {
	tree[rt].lazy = 0, tree[rt].len = (r - l + 1) * 1ll;
	if (l == r) {
		tree[rt].sum = 1ll;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson, l, mid), build(rson, mid + 1, r);
	push_up(rt);
}

void push_down(int rt) {
	if (!tree[rt].lazy) return;
	tree[lson].sum = ((q_pow(10, tree[lson].len) - 1ll + mod) % mod * tree[rt].lazy) % mod;
	tree[lson].sum = (tree[lson].sum * inv) % mod;
	tree[rson].sum = ((q_pow(10, tree[rson].len) - 1ll + mod) % mod * tree[rt].lazy) % mod;
	tree[rson].sum = (tree[rson].sum * inv) % mod;
	tree[lson].lazy = tree[rt].lazy;
	tree[rson].lazy = tree[rt].lazy;
	tree[rt].lazy = 0;
}

void change(int rt, ll col, int l, int r, int L, int R) {
	if (L <= l && r <= R) {
		tree[rt].sum = ((q_pow(10, tree[rt].len) - 1ll + mod) % mod * col) % mod;
		tree[rt].sum = (tree[rt].sum * inv) % mod;
		tree[rt].lazy = col;
		return;
	}
	push_down(rt);
	int mid = (l + r) >> 1;
	if (L <= mid) change(lson, col, l, mid, L, R);
	if (R > mid) change(rson, col, mid + 1, r, L, R);
	push_up(rt);
}

int main() {
	n = read(), m = read();
	build(1, 1, n);
	for (int i = 1; i <= m; i++) {
		ll l = read(), r = read(), c = read();
		change(1, c, 1, n, l, r);
		printf("%lld\n", tree[1].sum);
	}
	return 0;
}
posted @ 2020-09-27 10:56  Kersen  阅读(148)  评论(2)    收藏  举报