AcWing 239.奇偶游戏 (带权并查集/种类并查集)
题意:你和朋友玩游戏,有个一\(01\)序列,你每次给出一个区间,朋友会回答这个区间中的\(1\)的个数是奇数还是偶数,但是你亲爱的朋友可能在撒谎,问在哪个询问你能确定你的朋友在撒谎,输出回合数.
题解:假如区间\([l,r]\)所含的奇数个数为偶数的话,那么其前缀和\(s_{l-1}\)和\(s_r\)所含的\(1\)的个数一定同奇同偶,如果\([l,r]\)所含奇数个数为奇数,\(s_{l-1}\)和\(s_r\)奇偶性一定不同.
所以我们对前缀和\(s\)进行维护,如果\([l,r]\)为偶数,那么我们可以将区间\(s_{l-1}\)和\(s_r\)合并,并且它们之间的权值应该为\(0\),若为奇数则权值为\(1\),传递关系可以用异或来操作,核心思想依然是带权并查集,但是这题还需要离散化.
此处顺便附上种类并查集的做法
代码:
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#define ll long long
#define db double
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a/gcd(a,b)*b;}
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'|ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
int n;
int m;
int a,b;
string op;
int p[N];
int d[N];
unordered_map<int,int> S;
int get(int x){
if(S.count(x)==0) S[x]=++n;
return S[x];
}
int find(int x){
if(p[x]!=x){
int root=find(p[x]);
d[x]^=d[p[x]];
p[x]=root;
}
return p[x];
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
rep(i,1,10010) p[i]=i;
cin>>n>>m;
n=0;
int ans=m;
rep(i,1,m){
cin>>a>>b>>op;
a=get(a-1),b=get(b);
int fa=find(a);
int fb=find(b);
int t=0;
if(op=="odd") t=1;
if(fa==fb){
if((d[a]^d[b])!=t){
ans=i-1;
break;
}
}
else{
p[fa]=fb;
d[fa]=d[a]^d[b]^t;
}
}
cout<<ans<<'\n';
return 0;
}
**************************************************************
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#define ll long long
#define db double
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a/gcd(a,b)*b;}
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'|ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
int n,m;
int p[N];
int a,b;
string op;
unordered_map<int,int> S;
int get(int x){
if(S.count(x)==0) S[x]=++n;
return S[x];
}
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>m;
int cnt=10010/2;
n=0;
rep(i,1,10010) p[i]=i;
int ans=m;
rep(i,1,m){
cin>>a>>b>>op; //p[x]存偶数,p[x+n]存奇数
a=get(a-1),b=get(b);
if(op=="even"){
if(find(a+cnt)==find(b)){
ans=i-1;
break;
}
p[find(a)]=find(b);
p[find(a+cnt)]=find(b+cnt);
}
else{
if(find(a)==find(b)){
ans=i-1;
break;
}
p[find(a)]=find(b+cnt);
p[find(a+cnt)]=find(b);
}
}
cout<<ans<<'\n';
return 0;
}
AcWing 239.奇偶游戏 (带权并查集/种类并查集)的更多相关文章
- acwing 239. 奇偶游戏 并查集
地址 https://www.acwing.com/problem/content/241/ 小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个 ...
- AcWing 239. 奇偶游戏
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- 浅谈并查集&种类并查集&带权并查集
并查集&种类并查集&带权并查集 前言: 因为是学习记录,所以知识讲解+例题推荐+练习题解都是放在一起的qvq 目录 并查集基础知识 并查集基础题目 种类并查集知识 种类并查集题目 并查 ...
- AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- Cogs 1070. [焦作一中2012] 玻璃球游戏 带权并查集,逆序处理
题目: http://cojs.tk/cogs/problem/problem.php?pid=1070 1070. [焦作一中2012] 玻璃球游戏 ★ 输入文件:marbles.in 输出 ...
- 洛谷P5092 [USACO2004OPEN]Cube Stacking 方块游戏 (带权并查集)
题目描述 约翰和贝茜在玩一个方块游戏.编号为 1\ldots n 1-n 的 n n ( 1 \leq n \leq 30000 1≤n≤30000 )个方块正放在地上,每个构成一个立方柱. 游戏开始 ...
- CDOJ 1070 秋实大哥打游戏 带权并查集
链接 F - 秋实大哥打游戏 Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%lld & %llu Submit ...
- bzoj3376/poj1988[Usaco2004 Open]Cube Stacking 方块游戏 — 带权并查集
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3376 题目大意: 编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方 ...
- 【BZOJ 3376】[Usaco2004 Open]Cube Stacking 方块游戏 带权并查集
这道题一开始以为是平衡树结果发现复杂度过不去,然后发现我们一直合并而且只是记录到最低的距离,那么就是带权并查集了,带权并查集的权一般是到根的距离,因为不算根要好打,不过还有一些其他的,具体的具体打. ...
随机推荐
- Flutter 应用入门:路由管理
路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewContro ...
- spring boot项目问题汇总
spring遇到的问题汇总 有关日志的打印和日志如何使用 在实际项目中,我们的程序都是运行在linux上,有错误时也不能在本地的控制台上直观看到,所有合理打印日志对于程序员迅速定位到错误. 打印日志时 ...
- [Usaco2008 Nov]Buying Hay 购买干草
题目描述 约翰的干草库存已经告罄,他打算为奶牛们采购H(1≤H≤50000)磅干草,他知道N(1≤N≤100)个干草公司,现在用1到N给它们编号.第i个公司卖的干草包重量为Pi(1≤Pi≤5000)磅 ...
- Java程序入门
编写Java源程序 在d:\day01 目录下新建文本文件,完整的文件名修改为HelloWorld.java ,其中文件名为HelloWorld ,后缀名必须为.java . 用记事本打开 在文件中键 ...
- 生僻标签 fieldset 与 legend 的妙用
谈到 <fieldset> 与 <legend>,大部分人肯定会比较陌生,在 HTML 标签中,属于比较少用的那一批. 我最早知道这两个标签,是在早年学习 reset.css ...
- Linux定时任务crontab通俗易懂简单扼要地解析
1.安装crontab 在配置好yum源的情况下,直接执行如下命令即可: yum install crontab 2.查看当前环境上已经有的定时任务有哪些? 执行如下命令即可 crontab -l 如 ...
- XV6学习(1) Lab util
正在学习MIT的6.S081,把做的实验写一写吧. 实验的代码放在了Github上. 第一个实验是Lab util,算是一个热身的实验,没有涉及到系统的底层,就是使用系统调用来完成几个用户模式的小程序 ...
- SDNU_ACM_ICPC_2021_Winter_Practice_4th [个人赛]
传送门 D - Odd Divisor 题意: 给你一个n,问你n是否至少有一个奇数因子(这里题意没说清,没说是不是只有一个还是可以有多个!AC以后才发现是不止一个 思路: 如果这个数没有奇数因子,那 ...
- Vue整合swiper报错Could not compile template .....swiper\dist\css\swiper.css解决办法
问题描述 今天做一个前端项目,安装幻灯片插件vue-awesome-swiper后 运行npm run dev 后报错如下: `ERROR Could not compile template E:\ ...
- V2版的接口在V3版里面都能找到对应接口 数据结构
开发文档 - 微信支付商户平台 https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/api.shtml 版本选择 关闭 V2版接口和V3版接口实际 ...