AcWing 239. 奇偶游戏(带权并查集,扩展域并查集)

2024-04-16 00:48

本文主要是介绍AcWing 239. 奇偶游戏(带权并查集,扩展域并查集),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

小A和小B在玩一个游戏。

首先,小A写了一个由0和1组成的序列S,长度为N。

然后,小B向小A提出了M个问题。

在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个1。

机智的小B发现小A有可能在撒谎。

例如,小A曾经回答过 S[1~3] 中有奇数个1, S[4~6] 中有偶数个1,现在又回答 S[1~6] 中有偶数个1,显然这是自相矛盾的。

请你帮助小B检查这M个答案,并指出在至少多少个回答之后可以确定小A一定在撒谎。

即求出一个最小的k,使得01序列S满足第1k个回答,但不满足第1k+1个回答。

输入格式
第一行包含一个整数N,表示01序列长度。

第二行包含一个整数M,表示问题数量。

接下来M行,每行包含一组问答:两个整数l和r,以及回答“even”或“odd”,用以描述S[l~r] 中有偶数个1还是奇数个1。

输出格式
输出一个整数k,表示01序列满足第1k个回答,但不满足第1k+1个回答,如果01序列满足所有回答,则输出问题总数量。

数据范围
N≤109,M≤10000
输入样例:
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
输出样例:
3

边带权并查集好像忘得差不多了,赶紧复习一下

思路:
如果区间 [ l , r ] [l,r] [l,r]为奇数,代表 s u m [ l − 1 ] sum[l-1] sum[l1] s u m [ r ] sum[r] sum[r]的奇偶性不同,否则奇偶性相同。我们以此建立关系。

定义 d [ i ] d[i] d[i]代表 i i i与根节点的奇偶关系,如果为1代表奇偶性不同,否则奇偶性相同。关系传递直接通过关系相加再模2(因为相同奇偶性加上不改变,不同奇偶性加上改变)。

#include <ctime>
#include <iostream>
#include <assert.h>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
#include <map>using namespace std;
const int maxn = 2e5 + 7;
const int mod = 10007;int b[maxn],cnt;
int fa[maxn],d[maxn];
int n,m;struct Query {int l,r;int kind; //1代表奇数,0代表偶数
}q[maxn];int Find(int x) {return lower_bound(b + 1,b + 1 + cnt,x) - b;
}void Input() {scanf("%d%d",&n,&m);for(int i = 1;i <= m;i++) {char op[10];scanf("%d%d%s",&q[i].l,&q[i].r,op);if(op[0] == 'o') q[i].kind = 1;else q[i].kind = 0;b[++cnt] = q[i].l - 1;b[++cnt] = q[i].r;}sort(b + 1,b + 1 + cnt);cnt = unique(b + 1,b + 1 + cnt) - (b + 1);
}int findset(int x) {if(x == fa[x]) return x;int rt = findset(fa[x]);d[x] = (d[x] + d[fa[x]]) % 2;return fa[x] = rt;
}void Solve() {for(int i = 1;i <= cnt;i++) {fa[i] = i;}for(int i = 1;i <= m;i++) {int x = Find(q[i].l - 1),y = Find(q[i].r);int rx = findset(x),ry = findset(y);if(rx != ry) {fa[rx] = ry;d[rx] = (d[x] + d[y] + q[i].kind) % 2;} else {if((d[x] + d[y]) % 2 != q[i].kind) {printf("%d\n",i - 1);return ;}}}printf("%d\n",m);
}int main() {Input();Solve();return 0;
}

扩展域并查集:
定义x域为偶数域(或者是奇偶性相同),x+n域为奇数域(或者是奇偶性不同)
那么相同奇偶性的两个集和,奇偶性相同,所以偶数域和奇数域分别合并。
奇偶性不同的两个集和,就是偶数域合并另一个数的奇数域,奇数域合并另一个数的偶数域。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;const int maxn = 3e5 + 7;int fa[maxn];
int n,m,cnt;
int b[maxn];struct Query {int l,r;int kind;
}q[maxn];int Find(int x) {return lower_bound(b + 1,b + 1 + cnt,x) - b;
}int findset(int x) {if(x == fa[x]) return x;return fa[x] = findset(fa[x]);
}void Union(int x,int y) {int rx = findset(x),ry = findset(y);if(rx != ry) fa[rx] = ry;
}void Input() {scanf("%d%d",&n,&m);for(int i = 1;i <= m;i++) {char op[10];scanf("%d%d%s",&q[i].l,&q[i].r,op);b[++cnt] = q[i].l - 1;b[++cnt] = q[i].r;if(op[0] == 'o') q[i].kind = 1;else q[i].kind = 0;}sort(b + 1,b + 1 + cnt);cnt = unique(b + 1,b + 1 + cnt) - (b + 1);
}void Solve() {for(int i = 1;i <= 2 * cnt;i++) fa[i] = i;for(int i = 1;i <= m;i++) {int x = Find(q[i].l - 1),y = Find(q[i].r);if(q[i].kind == 0) {if(findset(x) == findset(y + cnt)) {printf("%d\n",i - 1);return;}Union(x,y);Union(x + cnt,y + cnt);}else {if(findset(x) == findset(y)) {printf("%d\n",i - 1);return;}Union(x,y + cnt);Union(x + cnt,y);}}printf("%d\n",m);
}int main() {Input();Solve();return 0;
}

这篇关于AcWing 239. 奇偶游戏(带权并查集,扩展域并查集)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907377

相关文章

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

poj 1182 并查集 食物链类

题意: 有n只动物,分别编号1....n。所有动物都属于A,B,C中的一种,已知A吃B,B吃C,C吃A。 按顺序给出下面两种共K条信息: 1. x 和 y 属于同一类。 2. x 吃 y 。 然而这些信息可能会出错,有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的 x 和 y 不在n的范围内。 求k条信息中有多少条是不正确的。 解析: 对于每只动物,创建3个元素 i

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

hdu1010 奇偶剪枝

恰好t时间到达 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.Arrays;import

POJ1988带权并查集

M u v 将u所在的堆移动到v所在的堆的上面 C u 求u的下面有多少块 带权并查集 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;i

POJ1703带权并查集

D: u v  u与v在不同的集合 A: u v  查询u与v的关系 1)压缩路径过程        fu->root   0  1  u-fu 0                 0  1   1                 1  0 2)合并过程 fu->fv      u->fu   0 1   v->fv 0            1 0 1            0

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @