题意

给出一张无向图,定义S[x]表示与点x直接相连的点集,有两个操作

1 x y表示将第x到第y条边状态变化(若存在则删除,不存在则建立)

2 x y询问S[x]与S[y]是否相等

题解

有一个技巧可以压缩的表示点集:给每个点随机一个key,S[x]就可以表示为

与x相连的点的key亦或起来。

考虑如何维护S[x], 因为修改操作是对输入的顺序的区间修改,我们就按边输入的

顺序进行分块,用sum[i][j]记录第i块对点j的贡献值,也就是如果第i块有一条边u-v

那么\(sum[i][u] \bigoplus= key[v], sum[i][v] \bigoplus= key[u]\)

查询一个点的点集就变成求\(sum[1][x] \bigoplus sum[2][x] \bigoplus sum[3][x] \cdots \bigoplus sum[num][x]\)

修改的时候如果修改区间落在不同的块上,对夹在中间的块打个lazy标记,表示查询的时候

不用亦或上这个块的贡献,对与两边块内的修改操作可以再用一个数组S记录暴力修改的状态,

比如要修改区间\([l,r]\)是块内的,那么就修改\(S[u[i]] \bigoplus= key[v[i]], S[v[i]] \bigoplus= key[u[i]] (i\in[l,r])\)

查询x的点集时再xor上S[x]就行,总的来说就是块间修改只需要对sum打标记,块内修改就

暴力更改S,最后复杂度\(O(q\sqrt m)\),分块的时候块数要开成\(1.5\sqrt m\)

代码

#include <bits/stdc++.h>

using namespace std;
const int mx = 2e5+10;
typedef long long ll; int belong[mx], block, num, l[mx], r[mx], id[mx];
int n, m, q, u[mx], v[mx];
int lazy[mx];
ll sum[450][mx], S[mx]; void build() {
block = 1.5*sqrt(m);
num = m / block;
if (m % block) num++;
for (int i = 1; i <= num; i++) {
l[i] = (i-1) * block + 1;
r[i] = i * block;
lazy[i] = 1;
for (int j = 1; j <= n; j++)
sum[i][j] = 0;
}
r[num] = m;
for (int i = 1; i <= m; i++)
belong[i] = (i-1) / block + 1;
for (int i = 1; i <= n; i++) S[i] = 0; } void update(int x, int y) {
if (belong[x] == belong[y]) {
for (int i = x; i <= y; i++) {
S[u[i]] ^= id[v[i]];
S[v[i]] ^= id[u[i]];
}
return;
}
int L = belong[x], R = belong[y];
for (register int i = x; i <= r[L]; i++) {
S[u[i]] ^= id[v[i]];
S[v[i]] ^= id[u[i]];
}
for (register int i = L+1; i < R; i++) lazy[i] ^= 1;
for (register int i = l[R]; i <= y; i++) {
S[u[i]] ^= id[v[i]];
S[v[i]] ^= id[u[i]];
}
} int main() {
srand(time(NULL));
for (int i = 1; i < 100005; i++) id[i] = rand() + 1;
int T;
scanf("%d", &T); while (T--) {
scanf("%d%d", &n, &m);
build();
for (int i = 1; i <= m; i++) {
scanf("%d%d", &u[i], &v[i]);
sum[belong[i]][u[i]] ^= id[v[i]];
sum[belong[i]][v[i]] ^= id[u[i]];
}
scanf("%d", &q);
while (q--) {
int op, x, y;
scanf("%d%d%d", &op, &x, &y);
if (op == 1) {
update(x, y);
} else {
ll ansx = S[x], ansy = S[y];
for (int i = 1; i <= num; i++) {
if (lazy[i]) {
ansx ^= sum[i][x];
ansy ^= sum[i][y];
}
}
putchar(ansx==ansy?'1':'0');
}
}
putchar('\n');
}
return 0;
}

A-Graph Games_2019牛客暑期多校训练营(第三场)的更多相关文章

  1. 2019牛客暑期多校训练营(第三场)H题目

    题意:给你一个N×N的矩阵,求最大的子矩阵 满足子矩阵中最大值和最小值之差小于等于m. 思路:这题是求满足条件的最大子矩阵,毫无疑问要遍历所有矩阵,并判断矩阵是某满足这个条件,那么我们大致只要解决两个 ...

  2. 2019牛客暑期多校训练营(第三场)- F Planting Trees

    题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...

  3. 2019牛客暑期多校训练营(第三场) F.Planting Trees(单调队列)

    题意:给你一个n*n的高度矩阵 要你找到里面最大的矩阵且最大的高度差不能超过m 思路:我们首先枚举上下右边界,然后我们可以用单调队列维护一个最左的边界 然后计算最大值 时间复杂度为O(n*n*n) # ...

  4. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  5. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  6. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  7. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  8. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  9. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  10. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

随机推荐

  1. Java编程基础阶段笔记 day 07 面向对象编程(上)

    ​ 面向对象编程 笔记Notes 面向对象三条学习主线 面向过程 VS 面向对象 类和对象 创建对象例子 面向对象的内存分析 类的属性:成员变量 成员变量 VS 局部变量 类的方法 方法的重载 可变个 ...

  2. 关于asp.net调用gemalto超级狗api的具体实现

    鉴于网上关于超级狗的具体操作并不详细,我把我所知道的写下来,希望能给有需求的网友做个参考.软件外壳保护我就不说了,没有什么难度,供应商也会提供文档,一步一步操作即可.我要说的是用于保护发给客户的程序, ...

  3. 【C++】string::substr函数

    形式:s.substr(p, n) 返回一个string,包含字符串s中从p开始的n个字符的拷贝(p的默认值是0,n的默认值是s.size() - p,即不加参数会默认拷贝整个s) int main( ...

  4. Vue 中使用 typescript

    Vue 中使用 typescript 什么是typescript typescript 为 javaScript的超集,这意味着它支持所有都JavaScript都语法.它很像JavaScript都强类 ...

  5. Sentry错误日志监控你会用了吗?

    无论作为新手还是老手程序员在程序的开发过程中,代码运行时难免会抛出异常,而且项目在部署到测试.生产环境后,我们便不可能像在开发时那样容易的及时发现处理错误了.一般我们都是在错误发生一段时间后,错误信息 ...

  6. WPF中ComboBox控件绑定键值对操作

    WPF中下拉框将键值对作为其数据源的具体操作.本实例以枚举类型以及枚举特性描述字符串生成键值对来进行. namespace ViewC { /// <summary> /// View.x ...

  7. 一个web前端开发者的日常唠叨

    时间飞逝,距离上一次更新博客已经过去了三个月,上一篇博客的发布时间停留在了4月4日. 近来三个月没有更新博客,深感抱歉和愧疚.停更博客就意味着学习的越来越少,作为一个普通的前端开发者来说这是万万不可取 ...

  8. SAP-采购订单跟踪报表

    *&---------------------------------------------------------------------**& Report ZMM_CGDDFX ...

  9. ArcGIS数据格式详解

  10. if else 深度优化

    一. if else表达式过于复杂 if ((condition1 && condition2 ) || ((condition2 || condition3) && ...