2026.07.25 模拟赛 比赛总结

2026.07.25 模拟赛 比赛总结

T1 T2 T3 T4 sum rk
70 WA - 20 WA 0 WA 90 8/20

其实 freopen 写炸了,这场保龄了。

link

T1 修改进制

考虑如果 \(a_i\)\(c\) 中出现过,那么第 \(i\) 个进制必不能用,否则 \(d\) 不可能是 \(a_i\) 的倍数。

同理,若 \(a_i\)\(c\) 中未出现过,那么第 \(i\) 个进制必须用,否则 \(d\) 就会是 \(a_i\) 的倍数。

于是得到做法:将 \(a\)\(c\) 中相同的部分一一对应地删去,后直接暴力算出 \(P\)\(D\) 的值判断即可。

理应是要用高精度的。拿个大质数取模去乱搞也可以过。

点击查看代码
#include <bits/stdc++.h>
#define il inline
#define int __int128

using namespace std;

bool Beg;
namespace Zctf1088 {
namespace IO {
	const int bufsz = 1 << 20;
	char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
	#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
	il int read() {
		int x = 0; char ch = getchar(); bool t = 0;
		while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
		while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
		return t ? -x : x;
	}
	char obuf[bufsz], *p3 = obuf, stk[50];
	#define flush() (fwrite(obuf, 1, p3 - obuf, stdout), p3 = obuf)
	#define putchar(ch) (p3 == obuf + bufsz && flush(), *p3++ = (ch))
	il void write(int x, bool t = 0) {
		int top = 0;
		x < 0 ? putchar('-'), x = -x : 0;
		do {stk[++top] = x % 10 | 48; x /= 10;} while(x);
		while (top) putchar(stk[top--]);
		t ? putchar(' ') : putchar('\n');
	}
	struct FL {
//		~FL() {flush();}
	} fl;
}
using IO::read; using IO::write;
const int MOD = 2000000000000000057;
const int N = 1e3 + 10;
int n, m, a[N], c[N], t[N];
int b[N], tot1, d[N], tot2;
il int fpow(int a, int x) {
	a %= MOD;
	int ans = 1;
	while (x) {
		if (x & 1) ans = ans * a % MOD;
		a = a * a % MOD;
		x >>= 1;
	}
	return ans;
}
signed main() {
//	freopen("cunhui.in", "r", stdin);
//	freopen("cunhui.out", "w", stdout);
	n = read(), m = read();
	for (int i = 1; i <= n; i++) a[i] = read();
	for (int i = 1; i <= m; i++) c[i] = read();
	for (int i = 1; i <= n; i++) {
		int fl = 1;
		for (int j = 1; j <= m && fl; j++) 
			fl &= (a[i] != c[j]);
		if (fl) b[++tot1] = a[i];
	}
	for (int i = 1; i <= m; i++) {
		int fl = 1;
		for (int j = 1; j <= n && fl; j++) {
			if (c[i] == a[j] && !t[j]) {
				fl = 0;
				t[j] = 1;
			}
		}
		if (fl) d[++tot2] = c[i];
	}
	int num = 1, tim = 1, sum = 0;
	for (int i = 1; i <= tot2; i++) 
		num = num * d[i] % MOD;
	for (int i = 1; i <= tot1; i++) 
		tim = tim * b[i] % MOD;
	for (int i = 1; i <= tot1; i++) 
		sum = (sum + tim * fpow(b[i], MOD - 2) % MOD) % MOD;
	if (sum == num) printf("S\n");
	else printf("N\n");
	return 0;
}}
bool End;
il void Usd() {cerr << "\nUse: " << (&Beg - &End) / 1024.0 / 1024.0 << "MB " << (double)clock() * 1000.0 / CLOCKS_PER_SEC << "ms\n";}
signed main() {
	Zctf1088::main();
	Usd();
	return 0;
}

T2 寻找小猫

显然树形 dp。

\(f_{i,k,0/1}\) 表示考虑到节点 \(i\),有 \(k\) 个叶子需要搜查,且否/是需要利用父亲的信息判断在不在这棵子树内,的最小代价。于是有转移:

\[\begin{align} f_{u,k,0} &= \min(\sum_{\sum k_i=k}f_{v,k_i,0},a_u+\min(\sum_{\sum k_i=k}\min(f_{v,k_i,0},f_{v,k_i,1})))\\ f_{u,k,1} &= \min(\sum_{\sum k_i=k} f_{v,k_i,0/1}(转移中只有一个 v 的第三维是 1)) \end{align} \]

对于 \(\sum k_i=k\) 的部分,存在树上背包经典 trick:对于每个点统计 \(siz_u\),表示 \(u\) 子树内叶子节点个数,于是 \(k_u \le siz_u\)。时间复杂度 \(O(nk)\)

点击查看代码
#include <bits/stdc++.h>
#define il inline
#define int long long

using namespace std;

bool Beg;
namespace Zctf1088 {
namespace IO {
	const int bufsz = 1 << 20;
	char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
	#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
	il int read() {
		int x = 0; char ch = getchar(); bool t = 0;
		while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
		while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
		return t ? -x : x;
	}
	char obuf[bufsz], *p3 = obuf, stk[50];
	#define flush() (fwrite(obuf, 1, p3 - obuf, stdout), p3 = obuf)
	#define putchar(ch) (p3 == obuf + bufsz && flush(), *p3++ = (ch))
	il void write(int x, bool t = 0) {
		int top = 0;
		x < 0 ? putchar('-'), x = -x : 0;
		do {stk[++top] = x % 10 | 48; x /= 10;} while(x);
		while (top) putchar(stk[top--]);
		t ? putchar(' ') : putchar('\n');
	}
	struct FL {
		~FL() {flush();}
	} fl;
}
using IO::read; using IO::write;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 5e3 + 10;
int n, a[N], t[N], tag[N], m, siz[N];
vector<int> G[N];
il void dfs(int x, int fa) {
	if (x != 1 && G[x].size() == 1) {
		tag[x] = 1;
		m++;
		return;
	}
	for (int y : G[x]) {
		if (y == fa) continue;
		dfs(y, x);
	}
}
il void upd(int &x, int y) {
	x = (x < y ? x : y);
}
int f[N][N][2], g[N], f1[N], g1[N], f2[N][2], g2[N][2];
il void dfs1(int x, int fa) {
	if (tag[x]) {
		f[x][0][0] = a[x];
		f[x][1][0] = 0;
		f[x][0][1] = 0;
		siz[x] = 1;
		return;
	}
	for (int y : G[x]) 
		if (y != fa) dfs1(y, x);
	for (int k = 0; k <= m; k++) 
		f[x][k][0] = f[x][k][1] = f1[k] = f2[k][0] = f2[k][1] = INF;
	f[x][0][0] = f1[0] = f2[0][0] = 0;
	for (int y : G[x]) if (y != fa) {
		for (int k = 0; k <= m; k++) {
			g[k] = f[x][k][0], f[x][k][0] = INF;
			g1[k] = f1[k], f1[k] = INF;
			g2[k][0] = f2[k][0], f2[k][0] = INF;
			g2[k][1] = f2[k][1], f2[k][1] = INF;
		}
		for (int i = 0; i <= siz[x]; i++) {
			for (int j = 0; j <= siz[y]; j++) {
				upd(f[x][i + j][0], g[i] + f[y][j][0]);
				upd(f1[i + j], g1[i] + min(f[y][j][0], f[y][j][1]));
				upd(f2[i + j][0], g2[i][0] + f[y][j][0]);
				upd(f2[i + j][1], g2[i][0] + f[y][j][1]);
				upd(f2[i + j][1], g2[i][1] + f[y][j][0]);
			}
		}
		siz[x] += siz[y];
	}
	for (int k = 0; k <= m; k++) {
		f[x][k][0] = min(f[x][k][0], a[x] + f1[k]);
		f[x][k][1] = f2[k][1];
	}
}
signed main() {
//	freopen("ct.in", "r", stdin);
//	freopen("ct.out", "w", stdout);
	n = read();
	for (int i = 1; i <= n; i++) a[i] = read();
	for (int i = 1; i <= n; i++) t[i] = read();
	for (int i = 1; i < n; i++) {
		int x = read(), y = read();
		G[x].push_back(y);
		G[y].push_back(x);
	}
	if (n == 1) return write(0), 0;
	dfs(1, 0);
	for (int i = 1; i <= n; i++) 
		for (int k = 0; k <= m; k++) f[i][k][0] = f[i][k][1] = INF;
	dfs1(1, 0);
	int ans = INF;
	for (int k = 0; k <= m; k++) 
		ans = min(ans, min(f[1][k][0], f[1][k][1]) + t[k]);
	write(ans);
	return 0;
}}
bool End;
il void Usd() {cerr << "\nUse: " << (&Beg - &End) / 1024.0 / 1024.0 << "MB " << (double)clock() * 1000.0 / CLOCKS_PER_SEC << "ms\n";}
signed main() {
	Zctf1088::main();
	Usd();
	return 0;
}

T3 平方操作

题目要求区间平方,区间求倒数和。

首先,不难发现,可以在最开始给每个 \(a_i\) 求倒数,于是查询操作转化为区间求和。

注意到经过 \(k\) 次修改后,\(x\) 变为 \(x^{2^k}\)。指数套指数,考虑欧拉定理,得:\(x^{2^k} \equiv x^{2^k \bmod 998244352}\pmod{998244353}\)

注意到 \(998244352=119*2^{23}\),且有同于性质:\(ad \equiv bd \pmod{cd} \Rightarrow a \equiv b \pmod c(d>0)\)。则当 \(k \le 24\) 时,\(2^k \bmod 998244352=2^{k-23}\bmod 119\)。则当 \(k \le 24\) 时,\(x\) 的值最多有 \(119\) 种,即存在长为 \(119\) 的循环节。

注意到 \(2^{24} \equiv 1 \pmod{119}\),于是循环节长度可减小至 \(24\)

考虑使用线段树维护每一个节点的值。对于前 \(23\) 次操作,考虑使用势能线段树维护。操作数大于 \(23\) 时,用另一棵动态开点线段树进行维护:考虑开 \(24\) 棵线段树,维护循环节。每次对区间 \([l,r]\) 进行操作时,将其在 \(24\) 棵线段树上对应的节点进行整体移动一位即可。就是相互嫁接节点。

时间复杂度 \(O((23+24)\log n)=O(47 \log n)\)

点击查看代码
#include <bits/stdc++.h>
#define il inline
#define int long long

using namespace std;

bool Beg;
namespace Zctf1088 {
namespace IO {
	const int bufsz = 1 << 20;
	char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
	#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
	il int read() {
		int x = 0; char ch = getchar(); bool t = 0;
		while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
		while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
		return t ? -x : x;
	}
	char obuf[bufsz], *p3 = obuf, stk[50];
	#define flush() (fwrite(obuf, 1, p3 - obuf, stdout), p3 = obuf)
	#define putchar(ch) (p3 == obuf + bufsz && flush(), *p3++ = (ch))
	il void write(int x, bool t = 0) {
		int top = 0;
		x < 0 ? putchar('-'), x = -x : 0;
		do {stk[++top] = x % 10 | 48; x /= 10;} while(x);
		while (top) putchar(stk[top--]);
		t ? putchar(' ') : putchar('\n');
	}
	struct FL {
		~FL() {flush();}
	} fl;
}
using IO::read; using IO::write;
const int MOD = 998244353;
const int N = 1e5 + 10;
int n, m, a[N];
il int fpow(int a, int x, int MOD) {
	a %= MOD;
	int ans = 1;
	while (x) {
		if (x & 1) ans = ans * a % MOD;
		a = a * a % MOD;
		x >>= 1;
	}
	return ans;
}
int s[N][30], num[N][30];
namespace Seg {
	struct node {
		int mn, s, root[24], lazy;
	} tree[N << 2];
	int sum[(N << 2) * 24];
	int tot, tmp[24];
	#define lc p << 1
	#define rc p << 1 | 1
	#define mid ((l + r) >> 1)
	il void pushup(int p) {
		tree[p].mn = min(tree[lc].mn, tree[rc].mn);
		tree[p].s = (tree[lc].s + tree[rc].s) % MOD;
		for (int k = 0; k < 24; k++) 
			sum[tree[p].root[k]] = (sum[tree[lc].root[k]] + sum[tree[rc].root[k]]) % MOD;
	}
	il void build(int p, int l, int r) {
		for (int k = 0; k < 24; k++) 
			tree[p].root[k] = ++tot;
		if (l == r) {
			for (int k = 0; k < 24; k++) 
				sum[tree[p].root[k]] = s[l][k];
			tree[p].s = num[l][tree[p].mn];
			return;
		}
		build(lc, l, mid), build(rc, mid + 1, r);
		pushup(p);
	}
	il void upd(int p, int k) {
		for (int i = 0; i < 24; i++) 
			tmp[i] = tree[p].root[i];
		for (int i = 0; i < 24; i++) 
			tree[p].root[i] = tmp[(i + k) % 24];
		tree[p].s = sum[tree[p].root[0]];
		tree[p].lazy += k;
	}
	il void pushdown(int p) {
		if (!tree[p].lazy) return;
		upd(lc, tree[p].lazy);
		upd(rc, tree[p].lazy);
		tree[p].lazy = 0;
	}
	il void update(int p, int l, int r, int x, int y) {
		if (l == x && y == r && tree[p].mn >= 23) return upd(p, 1);
		if (l == r) return tree[p].s = num[l][++tree[p].mn], void();
		pushdown(p);
		if (y <= mid) update(lc, l, mid, x, y);
		else if (x > mid) update(rc, mid + 1, r, x, y);
		else update(lc, l, mid, x, mid), update(rc, mid + 1, r, mid + 1, y);
		pushup(p);
	}
	il int query(int p, int l, int r, int x, int y) {
		if (l == x && y == r) return tree[p].s;
		pushdown(p);
		if (y <= mid) return query(lc, l, mid, x, y);
		else if (x > mid) return query(rc, mid + 1, r, x, y);
		else return (query(lc, l, mid, x, mid) + query(rc, mid + 1, r, mid + 1, y)) % MOD;
	}
}
signed main() {
//	freopen("snow.in", "r", stdin);
//	freopen("snow.out", "w", stdout);
	n = read(), m = read();
	for (int i = 1; i <= n; i++) a[i] = read();
	for (int i = 1; i <= n; i++) a[i] = fpow(a[i], MOD - 2, MOD);
	for (int i = 1; i <= n; i++) {
		for (int k = 0; k < 24; k++) {
			s[i][k] = fpow(a[i], fpow(2, k, 119) * (1 << 23), MOD);
			num[i][k] = fpow(a[i], (1 << k), MOD);
		}
	}
	Seg::build(1, 1, n);
	while (m--) {
		int op = read(), l = read(), r = read();
		if (op == 0) {
			Seg::update(1, 1, n, l, r);
		} else {
			write(Seg::query(1, 1, n, l, r));
		}
	}
	return 0;
}}
bool End;
il void Usd() {cerr << "\nUse: " << (&Beg - &End) / 1024.0 / 1024.0 << "MB " << (double)clock() * 1000.0 / CLOCKS_PER_SEC << "ms\n";}
signed main() {
	Zctf1088::main();
	Usd();
	return 0;
}

T4 网格刷墙

附上官方题解:

o_260801010447_203890328kjf.png (740×1180)

这个题解在维护方式上写得有些假。自己推一下。

分讨的四种情况中,第 1 种和第 4 种、第 2 种和第 3 种本质上就是转一下再跑一遍。

时间复杂度 \(O(n \log n)\)

点击查看代码
#include <bits/stdc++.h>
#define il inline
#define int long long

using namespace std;

bool Beg;
namespace Zctf1088 {
namespace IO {
	const int bufsz = 1 << 20;
	char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
	#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
	il int read() {
		int x = 0; char ch = getchar(); bool t = 0;
		while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
		while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
		return t ? -x : x;
	}
	char obuf[bufsz], *p3 = obuf, stk[50];
	#define flush() (fwrite(obuf, 1, p3 - obuf, stdout), p3 = obuf)
	#define putchar(ch) (p3 == obuf + bufsz && flush(), *p3++ = (ch))
	il void write(int x, bool t = 0) {
		int top = 0;
		x < 0 ? putchar('-'), x = -x : 0;
		do {stk[++top] = x % 10 | 48; x /= 10;} while(x);
		while (top) putchar(stk[top--]);
		t ? putchar(' ') : putchar('\n');
	}
	struct FL {
		~FL() {flush();}
	} fl;
}
using IO::read; using IO::write;
const int N = 1e5 + 10;
int n, m, kk, typ;
int cc[N];
struct node {
	int p, t;
	il bool operator < (const node & c) const {
		return t < c.t;
	}
} a0[N], a1[N];
struct preseg {
	struct node {
		int s, lazy;
	} tree[N << 2];
	#define lc p << 1
	#define rc p << 1 | 1
	#define mid ((l + r) >> 1)
	il void pushdown(int p) {
		if (!tree[p].lazy) return;
		tree[lc].lazy = tree[rc].lazy = tree[p].lazy;
		tree[lc].s = tree[rc].s = tree[p].s;
		tree[p].lazy = 0;
	}
	il void update(int p, int l, int r, int x, int y, int v) {
		if (l == x && y == r) return tree[p].s = tree[p].lazy = v, void();
		pushdown(p);
		if (y <= mid) update(lc, l, mid, x, y, v);
		else if (x > mid) update(rc, mid + 1, r, x, y, v);
		else update(lc, l, mid, x, mid, v), update(rc, mid + 1, r, mid + 1, y, v);
	}
	il int query(int p, int l, int r, int x) {
		if (l == r) return tree[p].s;
		pushdown(p);
		if (x <= mid) return query(lc, l, mid, x);
		else return query(rc, mid + 1, r, x);
	}
	#undef lc
	#undef rc
	#undef mid
} tr0, tr1;
namespace Lmx {
	int a[N], s[N];
	il int solve1() {
		sort(a0 + 1, a0 + 1 + n);
		sort(a1 + 1, a1 + 1 + m);
		int res = 0, sum = m - 1, ss = 0;
		for (int i = 0; i <= m + 1; i++) a[i] = -1;
		for (int i = 0; i <= kk; i++) s[i] = 0;
		for (int i = n, j = m; i >= 1; i--) {
			while (j >= 1 && a1[j].t > a0[i].t) {
				int p = a1[j].p, c = cc[a1[j].t];
				a[p] = c;
				if (p > 1) {
					if (a[p - 1] != -1) s[a[p - 1]]--;
					else s[a[p]]++, sum--;
				} 
				if (p < m) {
					if (a[p + 1] != -1) s[a[p + 1]]--;
					else s[a[p]]++, sum--;
				}
				ss += (a[p - 1] == c) + (a[p + 1] == c);
				j--;
			}
			int cnt = sum + s[cc[a0[i].t]] + ss;
			res += cnt;
		}
		return res;
	}
	il int solve() {
		int res = solve1();
		swap(n, m);
		swap(a0, a1);
		res += solve1();
		swap(n, m);
		swap(a0, a1);
		return res;
	}
}
namespace Dyc {
	int ii[N], id[N];
	namespace Seg {
		int tree[N << 2];
		#define lc p << 1
		#define rc p << 1 | 1
		#define mid ((l + r) >> 1)
		il void pushup(int p) {tree[p] = tree[lc] + tree[rc];}
		il void update(int p, int l, int r, int x, int v) {
			if (l == r) return tree[p] += v, void();
			if (x <= mid) update(lc, l, mid, x, v);
			else update(rc, mid + 1, r, x, v);
			pushup(p);
		}
		il int query(int p, int l, int r, int x, int y) {
			if (x > y) return 0;
			if (l == x && y == r) return tree[p];
			if (y <= mid) return query(lc, l, mid, x, y);
			else if (x > mid) return query(rc, mid + 1, r, x, y);
			else return query(lc, l, mid, x, mid) + query(rc, mid + 1, r, mid + 1, y);
		}
		il void init() {
			memset(tree, 0, sizeof(tree));
		}
		#undef lc
		#undef rc
		#undef mid
	}
	il void init() {
		Seg::init();
		for (int i = 1; i <= n; i++) ii[i] = 0;
		for (int i = 1; i <= m; i++) id[i] = 0;
	}
	il int solve() {
		sort(a0 + 1, a0 + 1 + n);
		sort(a1 + 1, a1 + 1 + m);
		for (int i = 1; i <= n; i++) 
			ii[a0[i].p] = i;
		for (int i = 1; i <= m; i++) 
			id[a1[i].p] = i;
		int res = 0;
		for (int i = n, j = m; i >= 1; i--) {
			while (j >= 1 && a1[j].t > a0[i].t) {
				int p = a1[j].p;
				if (p > 1 && cc[a1[j].t] == cc[a1[id[p - 1]].t] && id[p - 1] > j) {
					Seg::update(1, 0, kk, a1[id[p - 1]].t, 1);
					Seg::update(1, 0, kk, a1[j].t, 1);
				}
				if (p < m && cc[a1[j].t] == cc[a1[id[p + 1]].t] && id[p + 1] > j) {
					Seg::update(1, 0, kk, a1[id[p + 1]].t, 1);
					Seg::update(1, 0, kk, a1[j].t, 1);
				}
				j--;
			}
			int p = a0[i].p;
			if (p > 1 && ii[p - 1] > i) 
				res += Seg::query(1, 0, kk, a0[ii[p - 1]].t + 1, kk);
			if (p < n && ii[p + 1] > i) 
				res += Seg::query(1, 0, kk, a0[ii[p + 1]].t + 1, kk);
		}
		return res;
	}
}
namespace Dzb {
	int ii[N], id[N];
	int root[N];
	namespace Seg {
		struct node {
			int l, r, s;
		} tree[N << 5];
		int tot;
		#define lc tree[p].l
		#define rc tree[p].r
		#define mid ((l + r) >> 1)
		il void pushup(int p) {tree[p].s = tree[lc].s + tree[rc].s;}
		il void update(int &p, int l, int r, int x, int v) {
			if (!p) p = ++tot;
			if (l == r) return tree[p].s += v, void();
			if (x <= mid) update(lc, l, mid, x, v);
			else update(rc, mid + 1, r, x, v);
			pushup(p);
		}
		il int query(int p, int l, int r, int x, int y) {
			if (!p || x > y) return 0;
			if (l == x && y == r) return tree[p].s;
			if (y <= mid) return query(lc, l, mid, x, y);
			else if (x > mid) return query(rc, mid + 1, r, x, y);
			else return query(lc, l, mid, x, mid) + query(rc, mid + 1, r, mid + 1, y);
		}
		il void init() {
			for (int i = 0; i <= tot; i++) tree[i] = {0, 0, 0};
			tot = 0;
		}
		#undef lc
		#undef rc
		#undef mid
	}
	il void init() {
		Seg::init();
		for (int i = 0; i <= kk; i++) root[i] = 0;
		for (int i = 1; i <= n; i++) ii[i] = 0;
		for (int i = 1; i <= m; i++) id[i] = 0;
	}
	il int solve() {
		sort(a0 + 1, a0 + 1 + n);
		sort(a1 + 1, a1 + 1 + m);
		for (int i = 1; i <= n; i++) 
			ii[a0[i].p] = i;
		for (int i = 1; i <= m; i++) 
			id[a1[i].p] = i;
		int res = 0;
		for (int i = n, j = m; i >= 1; i--) {
			while (j >= 1 && a1[j].t > a0[i].t) {
				int p = a1[j].p;
				if (p > 1) Seg::update(root[cc[a1[j].t]], 0, kk, a1[id[p - 1]].t, 1);
				if (p < m) Seg::update(root[cc[a1[j].t]], 0, kk, a1[id[p + 1]].t, 1);
				j--;
			}
			int p = a0[i].p;
			if (p > 1) res += Seg::query(root[cc[a0[ii[p - 1]].t]], 0, kk, 0, a0[ii[p - 1]].t - 1);
			if (p < n) res += Seg::query(root[cc[a0[ii[p + 1]].t]], 0, kk, 0, a0[ii[p + 1]].t - 1);
		}
		return res;
	}
}
namespace Xzz {
	il int solve() {
		swap(n, m);
		swap(a0, a1);
		Dyc::init();
		int res = Dyc::solve();
		swap(n, m);
		swap(a0, a1);
		return res;
	}
}
namespace Wyl {
	il int solve() {
		swap(n, m);
		swap(a0, a1);
		Dzb::init();
		int res = Dzb::solve();
		swap(n, m);
		swap(a0, a1);
		return res;
	}
}
signed main() {
	n = read(), m = read(), kk = read(), typ = read();
	for (int i = 1; i <= kk; i++) {
		int op = read(), l = read(), r = read(), c = read();
		if (op == 0) tr0.update(1, 1, n, l, r, i);
		if (op == 1) tr1.update(1, 1, m, l, r, i);
		cc[i + 1] = c;
	}
	kk++;
	for (int i = 1; i <= n; i++) a0[i] = {i, tr0.query(1, 1, n, i) + 1};
	for (int i = 1; i <= m; i++) a1[i] = {i, tr1.query(1, 1, m, i) + 1};
	for (int i = 1; i <= m; i++) 
		if (a1[i].t == 1) a1[i].t = 0;
	int res1 = Lmx::solve();
	int res2 = Dyc::solve();
	int res3 = Dzb::solve();
	int res4 = Xzz::solve();
	int res5 = Wyl::solve(); res5 = 0;
	write(res1 + (res2 + res3 + res4 + res5) * typ);
	return 0;
}}
bool End;
il void Usd() {cerr << "\nUse: " << (&Beg - &End) / 1024.0 / 1024.0 << "MB " << (double)clock() * 1000.0 / CLOCKS_PER_SEC << "ms\n";}
signed main() {
	Zctf1088::main();
	Usd();
	return 0;
}
posted @ 2026-08-01 09:08  Zctf1088  阅读(16)  评论(0)    收藏  举报