P5937 题解

前言

题目传送门!

更好的阅读体验?

提供一种不用并查集的,非常好想的做法。

思路

题目就是说给定一堆 \(\sum\limits_{i=l}^r a_i \equiv w\pmod{2}\),判断哪个等式不合法。

这个形式明显可以前缀和优化:\(s_r - s_{l-1} \equiv w \pmod{2}\),其中 \(s_x = \sum\limits_{i=1}^x\)

发现这玩意类似差分约束。于是考虑建图。

对于上面的形式,连边 \((l-1) \xrightarrow{\large \ w\ } r\)

很自然地想到,如果当前查询的两个点 \((l - 1, r)\) 已经连通,他们可以直接计算出答案 \(ans\):走正向边 \(ans + w\),走反向边 \(ans - w\)

进一步地, 由于 \(ans\)\(w\) 都是 \(0\)\(1\),不用考虑加减。直接连双向边,答案就是两点的距离

最后就是如何计算两点的距离了:

  1. 可以直接 01bfs。
  2. 这个图在 \((u, v)\) 已经连通时不会再连边,说明它是一棵树。直接 dfs 即可。

记得离散化。时间复杂度 \(O(m^2)\),由于不可能建满边,所以跑得比预期快很多。

另外的

由于是一个树,应该可以倍增 lca 来实现 \(O(\log m)\) 加边与查询。

面前的大佬可以尝试写一下。

代码

#include <iostream>
#include <cstdio>
#include <unordered_map>
#include <algorithm>
using namespace std;
const int N = 10005;
struct Edge {int now, nxt, w;} e[N << 1];
int head[N], cur;
void add(int u, int v, int w)
{
	e[++cur].now = v, e[cur].nxt = head[u], e[cur].w = w;
	head[u] = cur;
}
struct Input {int l, r; string op;} input[N];
int tt[N << 1], tot;
int read()
{
	int x;
	cin >> x;
	tt[++tot] = x;
	return x;
}
int fin(int x) {return lower_bound(tt + 1, tt + tot + 1, x) - tt;}

bool vis[N];
int dis[N], emm[N];
void dfs(int u, int fa, int tag)
{
	emm[u] = tag;
	for (int i = head[u]; i; i = e[i].nxt)
	{
		int v = e[i].now;
		if (v == fa) continue;
		dis[v] = (dis[u] + e[i].w) % 2, dfs(v, u, tag);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; i++) input[i].l = read(), input[i].r = read(), cin >> input[i].op;
	sort(tt + 1, tt + tot + 1), tot = unique(tt + 1, tt + tot + 1) - tt - 1;
	for (int i = 1; i <= m; i++) input[i].l = fin(input[i].l - 1), input[i].r = fin(input[i].r);
	
	for (int i = 1; i <= m; i++)
	{
		int u = input[i].l, v = input[i].r, w = (input[i].op == "even" ? 0 : 1);
		dis[u] = 0, dfs(u, 0, i);
		if (emm[v] == i) //联通 
		{
			if (dis[v] != w) return cout << i - 1, 0;
		}
		else add(u, v, w), add(v, u, w), vis[u] = true, vis[v] = true;
	}
	cout << m;
	return 0;
}

希望能帮助到大家!

posted @ 2023-03-25 15:34  liangbowen  阅读(41)  评论(0编辑  收藏  举报