首页 > 其他分享 >P6185 序列 题解

P6185 序列 题解

时间:2024-03-01 09:24:24浏览次数:15  
标签:cnt P6185 ok int 题解 连通 vis 序列 clr

如果发现自己莫名其妙错了,可能是代码 UB,还开 O2!!!!!!!!!!!

传送门

首先,对于每个操作 2,将 \(u_i,v_i\) 连边。连边之后每个连通块内部可以在总和不变的情况下任意改变。

用并查集将每个连通块缩点,然后对于每个操作 1,将 \(u_i,v_i\) 连边。得到的图又会分成若干个连通块。判断整个图是否可行,只用判断每个连通块是否可行就行了。

我们想求出操作 1 的影响范围。发现沿着一条路径,路径上每一个点都可以传递这个 \(\pm 1\)。

  1. 如果该连通块是二分图,则当决定了一个操作 1 的起点,这个 \(\pm 1\) 就只能同时让两边加减,不能让任意两个点同时增加(减少)。这种情况下能达成目标,说明左部点和右部点总和相等。

  2. 如果该连通块不是二分图,肯定可以用路径传导的方式,让任意两个点同时增加(减少)。这种情况下能达成目标,说明 \(\sum b_i-a_i\) 是偶数。

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 5;
typedef long long ll;

int T;
int n, m;
int a[N], b[N];

int cnt = 0, p[N], q[N];

int fa[N], sz[N];
void init() {
	for (int i = 1; i <= n; i++)
		fa[i] = i, sz[i] = 1;
	return ;
}
int fnd(int x) {
	if (fa[x] == x)
		return x;
	return fa[x] = fnd(fa[x]);
}
void unn(int x, int y) {
	x = fnd(x), y = fnd(y);
	if (x == y)
		return ;
	if (sz[x] > sz[y])
		swap(x, y);
	fa[x] = y;
	sz[y] += sz[x];
	return ;
}

vector<int> e[N];
int vis[N];
ll cs[3] = {};
ll s[N]; 

bool dfs(int x, int clr) {
	cs[clr] += s[x];
	vis[x] = clr;
	bool ok = true;
	for (int i = 0; i < e[x].size(); i++) {
		if (vis[e[x][i]] && vis[x] == vis[e[x][i]])
			ok = false;
		if (!vis[e[x][i]] && !dfs(e[x][i], 3 - clr))
			ok = false;
	}
	return ok;
}

bool slv() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		e[i].clear();
		s[i] = 0;
		vis[i] = 0;
	}
	for (int i = 1; i <= n; i++)
		cin >> b[i];
	init();
	cnt = 0;
	for (int i = 1, o, x, y; i <= m; i++) {
		cin >> o >> x >> y;
		if (o == 1) {
			cnt++;
			p[cnt] = x, q[cnt] = y;
		}
		else
			unn(x, y);
	}
	for (int i = 1; i <= n; i++)
		s[fnd(i)] += b[i] - a[i];
	for (int i = 1; i <= cnt; i++) {
		e[fnd(p[i])].push_back(fnd(q[i]));
		e[fnd(q[i])].push_back(fnd(p[i]));
	}
	for (int i = 1; i <= n; i++)
		if (fnd(i) == i && !vis[i]) {
			cs[1] = cs[2] = 0;
			bool ok = dfs(i, 1);
			if (ok && cs[1] != cs[2])
				return false;
			if (!ok && ((cs[1] ^ cs[2]) % 2))
				return false;
		}
	return true;
}

int main() {
	cin >> T;
	while (T--) {
		if (slv())
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
	return 0;
}

标签:cnt,P6185,ok,int,题解,连通,vis,序列,clr
From: https://www.cnblogs.com/FLY-lai/p/18046125

相关文章

  • [ABC238F] Two Exams 题解
    [ABC238F]TwoExams题解思路解析这题很麻烦,因为有两个维度。所以可以想到先按照第一维排序,这样就不需要考虑第二维的问题。其次再发现数据范围小,可以想到能用dp做,接下来就考虑如何dp。首先我们要知道我们遍历到了第几个公民,同时还要知道还剩下几个代表名额,同时我们还需要思......
  • P8085 [COCI2011-2012#4] KRIPTOGRAM 题解
    P8085[COCI2011-2012#4]KRIPTOGRAM题解本文原发布于2024-02-07洛谷题库P8085[COCI2011-2012#4]KRIPTOGRAM题解区,现于2024-2-29转载至博客园思路解析这道题目的主要难点在于如何判断明文中形如\(\texttt{abcb}\)的子串可以和密文\(\texttt{bcac}\)匹配,因为如果......
  • 个人题解:江苏省选 2019 第二轮
    精准预测我们首先发现每个人每个时刻只有生死,所以我们可以建一个2-sat模型。每个人对应\(T+1\)个节点,表示这个人在每个时刻的生死。那么,题目的条件可以直接在这个模型上面建图,还要注意第\(t\)秒死亡可推出第\(t+1\)秒死亡和第\(t+1\)秒存活能推出第\(t\)秒存活的两......
  • 松散子序列
    题目: importosimportsysimportmathimportrefrombisectimport*fromheapqimport*input=lambda:sys.stdin.readline().rstrip('\r\n')defI():returninput()defII():returnint(input())defLII():returnlist(map(int,input.spli......
  • 后端项目打包相关问题解决
    在对项目进行打包后,我运行jar包发现出现下面错误:nomainmanifestattribute,in"app.jar" 在“app.jar”中没有主清单属性说明jar包里面的META-INF/MANIFEST.MF文件中没有Main-Class这个属性于是我解压jar包,到META-INF/MANIFEST.MF文件中手动添加了Main-Class: com.xxx.xx......
  • 2024年2月29号题解
    P1014[NOIP1999普及组]Cantor表解题思路和之前的蛇蝎矩阵很像,因此可以先构建一个蛇蝎矩阵因为是z形所以在每个奇数次矩阵的对角线进行交换就可以了,这样就得到了我们需要的矩阵代码实现#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#inclu......
  • 题解 CF1709 XOR
    *2400*dsuontree一道很好的题目思路很巧妙传送门题目大意给出一棵树,\(n\)个节点,每个节点有权值\(v\),定义一次操作为修改任意一个节点的值为任意正整数,要求最后的树不存在任意简单路径使得路径异或和为\(0\)Solution一个很常用的套路,先钦定根节点为\(1\)定义\(w......
  • CF1265E Beautiful Mirrors 题解
    CF1265EBeautifulMirrors题解题目大意题目传送门你有\(n\)个点,当你在第\(i\)个点时,有\(p_i\)的概率到达点\(i+1\),有\(1-p_i\)的概率回到点1。当到达点\(n+1\)时,游戏结束。且期望进行的游戏次数。\(1\len\le2\times10^5\)。题目分析设\(f_i\)表示到达点\(......
  • 代码随想录算法训练营第三十一天 | 53. 最大子序和, 376. 摆动序列,455.分发饼干
    455.分发饼干 已解答简单 相关标签相关企业 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] ......
  • P2606 [ZJOI2010] 排列计数 题解
    题意:求有多少个排列满足:对于每一个\(2\lei\len\),\(a_i>a_{\frac{i}{2}}\)。首先我们会发现这些数之间的大小关系形成了一个完全二叉树,因为每一个\(a_i\)都必须小于\(a_{2\timesi}\)和\(a_{2\timesi+1}\)。会发现本题的方案和每个位置具体的值并没有关系,而只......