洛谷 P5937 奇偶游戏

image

闲话

虽然这题好像找不到原题了,但毋庸置疑地说这的确是并查集的好题。

找到了 acwing

洛谷

分析

可以先对奇偶区间进行分析,当这个有偶数个 1 时,区间 \(1-(left-1)\) 一定与 区间 \(1-right\) 的奇偶性相同。

image

上面的图 \(3-4\) 为偶区间,根据分析,\(1-2\) 为奇区间。\(1-4\) 也为奇区间。

image

但如果填入的是个奇区间,那么 \(1-2\) 为奇区间,而 \(1-4\) 为偶区间。

知道这个性质我们就可以把奇数区间和偶数区间合并在一起,当遇到添加偶区间却遇到奇区间时就找到了矛盾。

我们可以用开二倍空间的数组分别存储奇区间和偶区间,其实分两个也行。

下见代码,注意这些(x-1)之类的都表示的是(1-(x-1))。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+100;//俩倍点
int a[N];
int n,q;
int fa[N];
int find(int x){
if(x==fa[x]){
return x;
}
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x);
y=find(y);
fa[y]=x;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>q;
for(int i=0;i<=N-66;i++){
fa[i]=i;
}
int cnt=0,ans=-1;
while(++cnt){
if(cnt>q){
break;
}
int x,y;
string s;
cin>>x>>y>>s;
if(s[0]=='e'){
//奇数和偶数会合并
if(find(x-1)==find(y+n)&&find(x-1+n)==find(y)){
ans=cnt;
break;
}
merge(x-1,y);//奇数
merge(x-1+n,y+n);//偶数
}
else{
//奇数与奇数,偶数与偶数会合并
if(find(x-1)==find(y)&&find(x-1+n)==find(y+n)){
ans=cnt;
break;
}
merge(x-1,y+n);//偶变奇
merge(x-1+n,y);//奇变偶
}
}
cout<<ans;
return 0;
}
posted @   sad_lin  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示