当前位置: 首页 > news >正文

每日一题8.23

种类并查集的两道题目

第一个题P5937 [CEOI 1999] Parity Game - 洛谷

Alice 和 Bob 在玩一个游戏:他写一个由 0 和 1 组成的序列。Alice 选其中的一段(比如第 3 位到第 5 位),问他这段里面有奇数个 1 还是偶数个 1。Bob 回答你的问题,然后 Alice 继续问。Alice 要检查 Bob 的答案,指出在 Bob 的第几个回答一定有问题。有问题的意思就是存在一个 01 序列满足这个回答前的所有回答,而且不存在序列满足这个回答前的所有回答及这个回答。

输入格式

第 1 行一个整数 n,是这个 01 序列的长度。

第 2 行一个整数 m,是问题和答案的个数。

第 3 行开始是问题和答案,每行先有两个整数,表示你询问的段的开始位置和结束位置。然后是 Bob 的回答。odd表示有奇数个 1,even 表示有偶数个 1。

输出格式

输出一行,一个数 x,表示存在一个 01 序列满足第 1 到第 x 个回答,但是不存在序列满足第 1 到第 x+1 个回答。如果所有回答都没问题,你就输出所有回答的个数。

输入输出样例

输入 #1复制

10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd

输出 #1复制

3

说明/提示

对于 100% 的数据,1≤n≤109,m≤5×103。

解决方案

根据前缀和可以分为两种并查集:a和b奇偶性相同和不同。分别分配到1~n和n+1~2n

比如x和y奇偶性相同的话就merge(x,y),merge(x+n,y+n)表示x和y是同一种类(即同奇偶性)

不同的话就merge(x,y+n),merge(x+n,y);表示x和y不是同一种类;

不过这个题还要离散化一下,代码如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 40000 + 10;
int fa[N];
struct node
{int x, y;string z;
}a[N];//设置一个结构体a方便离散化
void init()
{for (int i = 1; i <= N; i++)fa[i] = i;
}
int find(int x)
{if (fa[x] == x)return x;return fa[x] = find(fa[x]);
}
void merge(int x, int y)
{int fx = find(x), fy = find(y);if (fx!= fy)fa[fx] = fy;
}//并查集板子
inline void solve()
{int n,m;cin >> n >> m;if (!m){cout << 0 << endl;return;}init();vector<int>v;//储存着所有出现过的数然后离散化for (int i = 1; i <= m; i++){string z;int x, y;cin >> x >> y>> z;a[i] = {x-1, y, z};v.push_back(x-1);v.push_back(y);}sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()));//去重离散化int len = v.size();//一个种类的大小for (int i = 1; i <= m; i++){int x =lower_bound(v.begin(), v.end(), a[i].x) - v.begin(),y = lower_bound(v.begin(), v.end(), a[i].y) - v.begin();//找到输入的x,y在v中对应的编号char c=a[i].z[0];if (c == 'e')//说明要x和y同一奇偶性{if (find(x) == find(y + len))//如果x和y不是同奇偶性的话,就说明这句话不可能实现{cout<<i-1<<endl;return;}merge(x, y);merge(x+len, y + len);//合并}else//同理{if (find(x) == find(y)){cout << i - 1 << endl;return;}merge(x, y + len);merge(x + len, y);}}cout << m << endl;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;//cin >> t;while (t--){solve();}
}

 第二个题:P2024 [NOI2001] 食物链 - 洛谷

题目描述

动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A 吃 B,B 吃 C,C 吃 A。

现有 N 个动物,以 1∼N 编号。每个动物都是 A,B,C 中的一种,但是我们并不知道它到底是哪一种。

有人用两种说法对这 N 个动物所构成的食物链关系进行描述:

  • 第一种说法是 1 X Y,表示 X 和 Y 是同类。
  • 第二种说法是2 X Y,表示 X 吃 Y。

此人对 N 个动物,用上述两种说法,一句接一句地说出 K 句话,这 K 句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

  • 当前的话与前面的某些真的话冲突,就是假话;
  • 当前的话中 X 或 Y 比 N 大,就是假话;
  • 当前的话表示 X 吃 X,就是假话。

你的任务是根据给定的 N 和 K 句话,输出假话的总数。

输入格式

第一行两个整数,N,K,表示有 N 个动物,K 句话。

第二行开始每行一句话(按照题目要求,见样例)

输出格式

一行,一个整数,表示假话的总数。

输入输出样例

输入 #1复制

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

输出 #1复制

3

说明/提示

对于全部数据,1≤N≤5×104,1≤K≤105。

解决方案:

和第一个题类似也是一个种类并查集,但是这个题又三个种类,a,b,c,a吃b,b吃c,c吃a

a,b,c分别在1~n,n+1~2n,2n+1~3n;

所以要a和b是同一种类即

merge(x, y);
merge(x + n, y + n);
merge(x + 2 * n, y + 2 * n);

要a吃b即

merge(x, y + n);
merge(x + n, y + 2 * n);
merge(x + 2 * n, y);

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 400000 + 10;
int fa[N];
void init(int x)
{for (int i = 1; i <= x; i++)fa[i] = i;
}
int find(int x)
{if (fa[x] == x)return x;return fa[x] = find(fa[x]);
}
void merge(int x, int y)
{int fx = find(x), fy = find(y);if (fx != fy)fa[fx] = fy;
}//并查集板子
inline void solve()
{int n, m;cin >> n >> m;int op, x, y;init(3*n+100);vector<int> tab(3*n+100, 0);int res = 0;for (int i = 1; i <= m; i++){cin >> op >> x >> y;if (x > n || y > n){res++;continue;}if (op == 1){if (find(x) == find(y + n) || find(x) == find(y + 2 * n))//如果x吃y或者y吃x就说明x,y不可能是同一种类res++;else{merge(x, y);merge(x + n, y + n);merge(x + 2 * n, y + 2 * n);}}else{if (find(x) == find(y)||find(x)==find(y+2*n))//如果x和y是同一种类或者y吃x就不可能存在x吃yres++;else{merge(x, y + n);merge(x + n, y + 2 * n);merge(x + 2 * n, y);}}}cout << res << endl;
}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;//cin >> t;while (t--){solve();}
}

http://www.xdnf.cn/news/1354069.html

相关文章:

  • Windows应急响应一般思路(三)
  • 从词源和输出生成等角度详细解析PHP中常用文件操作类函数
  • BEVDet/BEVDet4D
  • 【40页PPT】数据安全动态数据脱敏解决方案(附下载方式)
  • LeetCode 分类刷题:2529. 正整数和负整数的最大计数
  • 【大语言模型 16】Transformer三种架构深度对比:选择最适合你的模型架构
  • XCVM1802-2MSEVSVA2197 XilinxAMD Versal Premium FPGA
  • flink常见问题之超出文件描述符限制
  • android studio配置 build
  • VS Code 中创建和开发 Spring Boot 项目
  • JWT实现Token登录验证
  • Nacos-11--Nacos热更新的原理
  • 语义普遍性与形式化:构建深层语义理解的统一框架
  • C++算法题—— 小C的细菌(二维偏序离线 + 树状数组 + 坐标压缩)
  • 使用Proxifier+vmware碰到的一些问题
  • JUC之虚拟线程
  • 论文阅读:Inner Monologue: Embodied Reasoning through Planning with Language Models
  • 173-基于Flask的微博舆情数据分析系统
  • 数据结构 之 【AVL树的简介与部分实现】(部分实现只涉及AVL树的插入问题,包括单旋((右单旋、左单旋))、双旋(左右单旋、右左单旋)等操作)
  • SAP FI 应收应付账龄分析
  • leetcode26:删除有序数组中的重复项Ⅰ(快慢指针解法)
  • X射线胸部肺炎检测:基于深度学习的医学影像分析项目
  • 概率论基础教程第六章 随机变量的联合分布(二)
  • 告别SaaS数据绑架,拥抱数据主权:XK+独立部署版跨境商城定制,为海外物流企业深度赋能
  • 遥感机器学习入门实战教程|Sklearn案例⑨:数据预处理(Processing)
  • 不用 if-else,Spring Boot 怎么知道 ?status=10 是哪个枚举?
  • 小白成长之路-k8s原理(一)
  • STM32学习笔记19-FLASH
  • [Mysql数据库] 选择备份策略选择题
  • 工业场景烟雾识别误报率↓82%!陌讯多模态融合算法实战解析