正睿 25 年省选联考 Day 7

正睿 25 年省选联考 Day 7

得分

T1 T2 T3 总分 排名
\(100\) \(0\) \(0\) \(100\) \(15/47\)

题解

T1 城市地平线

简单题。考虑从小到大删数,每一次删完后跨过当前数字的所有区间都是新的答案。假设当前位置左边有 \(a\) 个数,右边有 \(b\) 个数,那么长度为 \(i\) 的区间的方案数为 \(\min(i-1,b)-\max(1,i-a)+1\),拆开后分类讨论一下,可以简单用树状数组维护出每种区间的数量。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int Maxn = 2e5 + 5;
const int Inf = 2e9;

int n, L, R;
int a[Maxn], pos[Maxn];

struct BIT {
	int c[Maxn];
	int lowbit(int x) {return x & (-x);}
	void mdf(int x, int val) {for(int i = x; i <= n; i += lowbit(i)) c[i] += val;}
	int query(int x) {int sum = 0;for(int i = x; i; i -= lowbit(i)) sum += c[i]; return sum;}
	void mdf(int l, int r, int val) {mdf(l, val), mdf(r + 1, -val);}
}B1, B2, B3;

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> L >> R;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
		pos[a[i]] = i;
		B1.mdf(i, 1);
	}
	for(int i = 1; i <= n; i++) {
		B3.mdf(i, i, n - i + 1);
	}
	for(int i = 1; i <= n; i++) {
		int p = pos[i];
		if(!p) continue;
		B1.mdf(p, -1); 
		int a = B1.query(p - 1), b = B1.query(n) - B1.query(p), s = min(a, b);
		if(!s) continue;
		B3.mdf(2, a + b, a);
		if(2 <= b + 1) B2.mdf(2, b + 1, 1);
		if(b + 2 <= a + b) B3.mdf(b + 2, a + b, b + 1);
		if(2 <= a + 1) B3.mdf(2, a + 1, -(a + 1));
		if(a + 2 <= a + b) B2.mdf(a + 2, a + b, -1);
	}
	int ans = 0;
	for(int i = L; i <= R; i++) {
		int res = B2.query(i) * i + B3.query(i);
		ans ^= res;
	}
	cout << ans << '\n';
	return 0;
}

T2 合成史莱姆

首先考虑普通情况,容易发现史莱姆合并的过程对最终答案没有影响,只需要考虑每个史莱姆移到每一个餐盘的概率即可。考虑设 \(f(i,j)\) 表示所有史莱姆经过格子 \((i,j)\) 的总次数的期望,然后从这个格子走出棋盘的概率就是 \(\tfrac 14 f(i,j)\)。我们有如下转移:

\[f(i,j)=\dfrac{1}{4}\sum f(x,y)+a(i,j) \]

其中 \((x,y)\)\((i,j)\) 相邻,\(a(i,j)\) 表示该位置初始有无史莱姆。显然我们可以高斯消元 \(O(n^3)\) 求出答案。

考虑优化,在矩形上进行高斯消元有一个经典套路,我们设第一行为主元,以此表示后面的位置,用最后一行列方程,这样变量数就是 \(O(\sqrt n)\) 的,复杂度 \(O(n\sqrt n)\)

考虑在棋盘上进行这个过程,我们可以找一个格子为起点,然后进行广搜,如果当前格子无法用相邻格子表示则新设一个主元,否则用当前设的未知数表示。并且每次我们得出一个点的表达式后要再深搜一次,在不设新未知数的情况下尽可能多得出一些格子的表达式。可以证明这样的复杂度是正确的。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int Maxn = 2e5 + 5;
const int Inf = 2e9;
const int Mod = 998244353;
const int Inv4 = 748683265;

int add(int x, int y) {return x + y >= Mod ? x + y - Mod : x + y;}
int del(int x, int y) {return x - y < 0 ? x - y + Mod : x - y;}

int n;
struct node {
	int x, y, t;
}a[Maxn];
int mn[Maxn], mx[Maxn];
vector <int> v[Maxn];
#define pii pair<int, int>
#define mk make_pair
map <pii, int> mp, ans;
vector <int> tar;

int qpow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1) res = res * a % Mod;
		a = a * a % Mod; b >>= 1;
	}
	return res;
}

int tot = 0;
int val[805];
int nx[] = {1, -1, 0, 0};
int ny[] = {0, 0, 1, -1};
struct Coef{
	int a[805];
	int& operator[](int x) {return a[x];}
	Coef operator + (Coef b) {
		Coef c;
		for(int i = 0; i <= tot; i++) c[i] = add(a[i], b[i]);
		return c;
	}
	Coef operator - (Coef b) {
		Coef c;
		for(int i = 0; i <= tot; i++) c[i] = del(a[i], b[i]);
		return c;
	}
	Coef operator - (int b) {
		Coef c = *this; c[0] = del(c[0], b);
		return c;
	}
	Coef operator + (int b) {
		Coef c = *this; c[0] = add(c[0], b);
		return c;
	}
	Coef operator * (int b) {
		Coef c;
		for(int i = 0; i <= tot; i++) c[i] = a[i] * b % Mod;
		return c;
	}
	int calc() {
		int res = a[0];
		for(int i = 1; i <= tot; i++) res = add(res, a[i] * val[i] % Mod);
		return res;
	}
}mat[40005], eq[805];

queue <int> q;
bool vis[Maxn], limed[Maxn];

void dfs(int x) {
	int dx = a[x].x, dy = a[x].y;
	int t1 = mp[mk(dx, dy - 1)], t2 = mp[mk(dx - 1, dy)], t3 = mp[mk(dx, dy + 1)], t4 = mp[mk(dx + 1, dy)];
	int num = vis[t1] + vis[t3] + vis[t2] + vis[t4], cnt = (t1 != 0) + (t2 != 0) + (t3 != 0) + (t4 != 0);
	if(num == cnt - 1) {
		limed[x] = 1;
		Coef F = (mat[x] - a[x].t) * 4 - mat[t1] - mat[t2] - mat[t3] - mat[t4];
		if(t1 && !vis[t1]) mat[t1] = F, vis[t1] = 1, dfs(t1), q.push(t1);
		if(t2 && !vis[t2]) mat[t2] = F, vis[t2] = 1, dfs(t2), q.push(t2);
		if(t3 && !vis[t3]) mat[t3] = F, vis[t3] = 1, dfs(t3), q.push(t3);
		if(t4 && !vis[t4]) mat[t4] = F, vis[t4] = 1, dfs(t4), q.push(t4);
	}
}

void bfs(int S) {
	q.push(S);
	mat[S][++tot] = 1;
	vis[S] = 1;
	while(!q.empty()) {
		int u = q.front(); q.pop();
		int x = a[u].x, y = a[u].y;
		if(limed[u]) continue;
		int num = 0, pos[4] = {u, 0, 0, 0}, cnt = 0;
		for(int i = 0; i < 4; i++) {
			int rx = x + nx[i], ry = y + ny[i], id = mp[mk(rx, ry)];
			if(!id) continue; cnt++;
			if(vis[id]) pos[++num] = id;
		}
		for(int i = 0; i < 4; i++) {
			int rx = x + nx[i], ry = y + ny[i], id = mp[mk(rx, ry)];
			if(!id || vis[id]) continue;
			limed[u] = 1;
			if(num != cnt - 1) {
				mat[id][++tot] = 1;
				pos[++num] = id;
			}
			else {
				mat[id] = (mat[pos[0]] - a[pos[0]].t) * 4 - mat[pos[1]] - mat[pos[2]] - mat[pos[3]];
			}
			q.push(id); vis[id] = 1;
			dfs(id);
		}
	}
}

void gauss(int m) {
	for(int i = 1; i <= m; i++) eq[i][0] = (Mod - eq[i][0]) % Mod;
	for(int i = 1; i <= m; i++) {
		int u = i;
		for(int j = 1; j <= m; j++) {
			if(eq[j][j] && j < i) continue;
			if(eq[j][i] > eq[u][i]) u = j;
		}
		swap(eq[u], eq[i]);
		for(int j = 1; j <= m; j++) {
			if(i != j) {
				int p = eq[j][i] * qpow(eq[i][i], Mod - 2) % Mod;
				eq[j] = eq[j] - eq[i] * p;
			}
		}
	}
	for(int i = 1; i <= m; i++) {
		val[i] = eq[i][0] * qpow(eq[i][i], Mod - 2) % Mod;
	}
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	mt19937 rnd(time(0));
	cin >> n;
	for(int i = 1; i <= n; i++) {
		cin >> a[i].x >> a[i].y >> a[i].t;
		mp[mk(a[i].x, a[i].y)] = i;
	}
	int start = 1; 
	bfs(start);
	int m = 0;
	for(int i = 1; i <= n; i++) {
		if(limed[i]) continue;
		int dx = a[i].x, dy = a[i].y;
		int t1 = mp[mk(dx, dy - 1)], t2 = mp[mk(dx - 1, dy)], t3 = mp[mk(dx, dy + 1)], t4 = mp[mk(dx + 1, dy)];
		eq[++m] = (mat[t1] + mat[t2] + mat[t3] + mat[t4]) * Inv4 + a[i].t - mat[i];
	}
	gauss(tot);
	for(int i = 1; i <= n; i++) {
		int num = mat[i].calc() * Inv4 % Mod;
		for(int j = 0; j < 4; j++) {
			int px = a[i].x + nx[j], py = a[i].y + ny[j];
			if(!mp[mk(px, py)]) (ans[mk(px, py)] += num) %= Mod;
		}
	}
	int res = 0;
	for(auto i : ans) res ^= i.second;
	cout << res << '\n';
	return 0;
}

T3 维修喷水管

出题人自己发明的科技,改不了一点。

posted @ 2025-02-23 22:05  UKE_Automation  阅读(38)  评论(0)    收藏  举报