2017年10月6日提高组T2 有趣的异或
来源:互联网 发布:js为标签添加属性 编辑:程序博客网 时间:2024/06/05 16:21
Description
Input
Output
Hint
Solution
看到判断真假条件的都要想到并查集了(哭
但是这里我并没有用并查集做法
考虑我们如果已经得到了目标序列a,并记录一个前缀异或数组s,则对于全部的询问l, r, k都要满足s[r]xor s[l-1]=k。那么我们对于一个操作l, r, k,若l-1和r同属于一个集合就判断他们之间的路径是否为k,若他们不属于同一个集合就连权为k的边合并
这里在合并的时候有一个技巧就是小的并上大的,这样每次dfs小集合更改异或值的时候就总的复杂度就是NlogN了
对于每一个独立的集合,只要任意一个数字确定了剩下的数字就都确定了。那么每个集合内第一个遇到的数字填0就可以了。注意一下这里的0是序列a的值,并不是前缀异或和s
Code
#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include <algorithm>#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)#define erg(i, st) for (int i = ls[st]; i; i = e[i].next)#define fill(x, t) memset(x, t, sizeof(x))#define max(x, y) ((x)>(y)?(x):(y))#define min(x, y) ((x)<(y)?(x):(y))#define abs(x) ((x)<(0)?(-(x)):(x))#define N 400001#define E N << 2 | 1#define L 11struct edge {int x, y, w, next;} e[E];int used[N], size[N], dis[N], fa[N], ls[N], edgeCnt = 0;inline int read() { int x = 0; char ch = getchar(); for(; ch<'0'||ch>'9'; ch=getchar()); for(; ch<='9'&&ch>='0'; (x*=10)+=ch-'0',ch=getchar()); return x;}inline void writeln(int x){ char ch[L] = {}; int i = 0; do {ch[++ i] = '0' + x % 10;} while (x /= 10); while (i) putchar(ch[i --]); putchar('\n');}inline void addEdge(int x, int y, int w) { e[++ edgeCnt] = (edge) {x, y, w, ls[x]}; ls[x] = edgeCnt; e[++ edgeCnt] = (edge) {y, x, w, ls[y]}; ls[y] = edgeCnt;}inline void swap(int &x, int &y) { x ^= y; y ^= x; x ^= y;}inline int getFather(int now) { return ((now == fa[now])?(now):(fa[now] = getFather(fa[now])));}inline int getDis(int x, int y) { return dis[x] ^ dis[y];}inline void dfs(int f, int now) { used[now] = 1; erg(i, now) { if (e[i].y == f) { continue; } dis[e[i].y] = dis[now] ^ e[i].w; dfs(now, e[i].y); }}int main(void) { int n = read() + 1; int m = read(); int czy = read(); int lastAns = 0; rep(i, 1, n) { fa[i] = i; size[i] = 1; } while (m --) { int l = read() ^ (czy * lastAns); int r = read() ^ (czy * lastAns); int k = read() ^ (czy * lastAns); r += 1; int fl = getFather(l); int fr = getFather(r); if (fl == fr) { lastAns = (k == getDis(l, r)); } else { addEdge(l, r, k); if (size[fl] < size[fr]) { swap(l, r); swap(fl, fr); } size[fl] += size[fr]; dis[r] = dis[l] ^ k; dfs(l, r); fa[fr] = fl; lastAns = 1; } writeln(lastAns); } fill(used, 0); rep(i, 1, n) { if (!used[i]) { dis[i] = dis[i - 1]; dfs(0, i); } } rep(i, 2, n) { int prt = getDis(i, i - 1); writeln(prt); } return 0;}
阅读全文
0 0
- 2017年10月6日提高组T2 有趣的异或
- 2017年10月6日提高组T2 挖矿
- 2017年10月6日提高组T2 挖矿
- 2017年10月23日提高组T2 灵知的太阳信仰
- 【SSLGZ 2790】2017年10月25日提高组T2 次方的运算
- SSL2790 2017年10月25日提高组T2 次方的运算(math)
- SSL2759 2017年10月6日提高组T2 挖矿(dp)
- 2017年10月6日提高组T2 猫公司
- 2017年8月9日提高组T2 覆盖
- 2017年8月9日提高组T2 覆盖
- 2017年8月9日提高组T2 覆盖
- 2017年8月15日提高组T2 购买
- 2017年8月14日提高组T2 温度
- 2017年8月15日提高组T2 购买
- 2017年8月16日提高组T2 疾病
- 2017年8月17日提高组T2 考试
- 2017年9月16日提高组T2 A
- 2017年11月1日提高组T2 树论
- shiro授权源码
- python做词云Wordcloud
- spring回顾系列:依赖注入
- LeetCode283. Move Zeroes 解答
- struts2中拦截器的使用
- 2017年10月6日提高组T2 有趣的异或
- 【TensorFlow】tf.nn.conv2d是怎样实现卷积的?
- <Linux>压缩解压常用命令
- maven 的私库和镜像的配置
- Stanford nlp 初步之词性标注
- String类型
- Linux SPI总线设备驱动模型详解
- hdu 3478 Catch(判断奇数环)
- 使用栈进行进制转换