@description@

给定一个 n 个点的无向图,标号从 1 到 n。一开始没有任何边存在。

请你完成以下两种操作:

1 x y(1 <= x, y <= n, x ≠ y),将 (x, y) 这一条边置反。也就是,存在变为不存在,不存在变为存在。

2 x y(1 <= x, y <= n, x ≠ y),询问 x, y 是否连通。

注意操作是加密的。记 last 表示上一次 2 操作的结果(连通为 1,否则为 0),初始为 0。

则真实的询问编号 x', y' 应为 (x + last - 1) mod n + 1,(y + last - 1) mod n + 1。

Input

第一行输入两个整数 n, m,表示点数与操作数。

接下来 m 行,每行三个整数,描述了一次操作。

Output

输出一个字符串,第 i 个字符表示第 i 次 2 操作的答案。

Examples

Input

5 9

1 1 2

1 1 3

2 3 2

1 2 4

2 3 4

1 2 4

2 3 4

1 1 3

2 4 3

Output

1010

@solution@

(据说做法很多,不过我觉得官方题解挺好的,所以就只写了官方题解的方法)

众所周知codeforces的在线修改查询都是通过交互实现的,所以这个题一定是假在线。

这道题其实是一道很经典的模型:动态图问题。即在动态加边删边中维护整张图的连通性。

而众所周知的动态图解法如 lct,线段树分治 + 并查集等都是要支持离线的。

但其实,这道题所谓的在线只有两种情况 last = 0 与 last = 1。

至少我们还是不能用 lct,因为 lct 需要知道一条边被删除的时间。

考虑使用一些更暴力的方法,比如——对询问分块。

我们将询问分成 Q 块。感性点的思路是:之前的整块大力重构维护出一个信息,零散的操作暴力算它的贡献。

更进一步地,假如我们处理第 i 块的询问时。

先找出第 i 块中可能涉及到的边(即 last = 0/1 分别对应的边),这样的边一共会有 2*m/Q 条。

然后对于 1~i-1 块这些加删边,如果第 i 块中没有涉及,就统计一条边被操作的次数,使用并查集缩点。这部分的总复杂度是 O(Q*m)。

如果涉及到了,就建出一个图。因为只拿涉及到的边建图,所以总边数 < 2*m/Q。

然后对于散块,操作时标记图中的边出现还是不出现,查询暴力 dfs。

因为图中的边数 < 2*m/Q,所以 dfs 复杂度为 O(m/Q)。dfs 这部分的总复杂度为 O(m^2/Q)。

那么总复杂度为 O(Q*m + m^2/Q)。当 Q = √m 时,取最小值 O(m√m)。

@accepted code@

#include<map>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(G, x) for(Graph::edge *p = G.adj[x];p;p = p->nxt)
#define pii pair<int, int>
#define fi first
#define se second
const int MAXN = 400000;
const int SQRT = 450;
struct Graph{
struct edge{
int to, id;
edge *nxt;
}edges[MAXN + 5], *adj[MAXN + 5], *ecnt;
void clear(int n) {
ecnt = &edges[0];
for(int i=1;i<=n;i++)
adj[i] = NULL;
}
void addedge(int u, int v, int id) {
edge *p = (++ecnt);
p->to = v, p->id = id, p->nxt = adj[u], adj[u] = p;
p = (++ecnt);
p->to = u, p->id = id, p->nxt = adj[v], adj[v] = p;
}
}G;
int le[MAXN + 5], ri[MAXN + 5], num[MAXN + 5], bcnt;
void init(int m) {
for(int i=1;i<=m;i++) {
if( (i - 1) % SQRT == 0 )
bcnt++, le[bcnt] = i;
ri[bcnt] = i, num[i] = bcnt;
}
}
int fa[MAXN + 5];
int find(int x) {
return fa[x] = (fa[x] == x ? x : find(fa[x]));
}
void unite(int x, int y) {
int fx = find(x), fy = find(y);
if( fx != fy )
fa[fx] = fy;
}
vector<pii>e;
bool tag[MAXN + 5]; int tg2[MAXN + 5];
void update(int p) {
if( tg2[p] == -1 ) {
G.addedge(find(e[p].fi), find(e[p].se), p);
tg2[p] = 1;
}
else tg2[p] ^= 1;
}
map<pii, int>mp;
int id(pii p) {
if( p.fi > p.se ) swap(p.fi, p.se);
if( mp.count(p) ) return mp[p];
else {
e.push_back(p);
return mp[p] = e.size() - 1;
}
}
bool vis[MAXN + 5];
void dfs(int x, bool f) {
if( vis[x] == f ) return ;
vis[x] = f;
rep(G, x) {
if( tg2[p->id] )
dfs(p->to, f);
}
}
bool query(int p) {
dfs(find(e[p].fi), true);
bool ret = vis[find(e[p].se)];
dfs(find(e[p].fi), false);
return ret;
}
bool lans[MAXN + 5];
int t[MAXN + 5], qry[2][MAXN + 5];
int n, m;
int main() {
scanf("%d%d", &n, &m), init(m);
for(int i=1;i<=m;i++) {
int x, y;
scanf("%d%d%d", &t[i], &x, &y);
qry[0][i] = id(make_pair(x, y));
x = x % n + 1, y = y % n + 1;
qry[1][i] = id(make_pair(x, y));
}
int lastans = 0;
for(int i=1;i<=bcnt;i++) {
for(int j=1;j<le[i];j++) {
tag[qry[lans[j]][j]] = false;
tg2[qry[lans[j]][j]] = -1;
}
for(int j=le[i];j<=ri[i];j++) {
tag[qry[0][j]] = tag[qry[1][j]] = true;
tg2[qry[0][j]] = tg2[qry[1][j]] = -1;
}
for(int j=1;j<=n;j++) fa[j] = j;
G.clear(n);
for(int j=1;j<le[i];j++)
if( t[j] == 1 && !tag[qry[lans[j]][j]] ) {
if( tg2[qry[lans[j]][j]] == -1 ) tg2[qry[lans[j]][j]] = 1;
else tg2[qry[lans[j]][j]] ^= 1;
}
for(int j=1;j<le[i];j++)
if( t[j] == 1 && !tag[qry[lans[j]][j]] && tg2[qry[lans[j]][j]] ) {
unite(e[qry[lans[j]][j]].fi, e[qry[lans[j]][j]].se);
}
for(int j=1;j<le[i];j++)
if( t[j] == 1 && tag[qry[lans[j]][j]] )
update(qry[lans[j]][j]);
for(int j=le[i];j<=ri[i];j++) {
if( t[j] == 1 )
update(qry[lastans][j]), lans[j] = lastans;
else lastans = lans[j] = query(qry[lastans][j]);
}
}
for(int i=1;i<=m;i++)
if( t[i] == 2 )
putchar(char(lans[i]) + '0');
}

@details@

对询问分块之类的题,虽然很少见,但其实非常巧妙。

而且代码量比起直接上大数据结构模板,往往能减少很多。

@codeforces - 1217F@ Forced Online Queries Problem的更多相关文章

  1. 【CF1217F】Forced Online Queries Problem

    题意 题目链接 动态图连通性,加密方式为 \((x+l-1)\bmod n +1\) (\(l=[上一次询问的两点连通]\)). 点数 \(n\),操作数 \(m\) \(\le 2\times 10 ...

  2. [cf1217F]Forced Online Queries Problem

    可以用并查集维护连通性,删除可以用按置合并并查集,但删掉一条边后无法再维护两点的联通性了(因为产生环的边是不加入的)暴力思路是, 考虑前i个操作后边的集合,暴力加入即可,但复杂度是$o(n^2)$的用 ...

  3. CodeForces - 369E Valera and Queries(树状数组)

    CodeForces - 369E Valera and Queries 题目大意:给出n个线段(线段的左端点和右端点坐标)和m个查询,每个查询有cnt个点,要求给出有多少条线段包含至少其中一个点. ...

  4. codeforces 1217E E. Sum Queries? (线段树

    codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...

  5. codeforces 797 E. Array Queries【dp,暴力】

    题目链接:codeforces 797 E. Array Queries   题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...

  6. [Codeforces 863D]Yet Another Array Queries Problem

    Description You are given an array a of size n, and q queries to it. There are queries of two types: ...

  7. Yet Another Array Queries Problem CodeForces - 863D (暴力/思维)

    You are given an array a of size n, and q queries to it. There are queries of two types: 1 li ri — p ...

  8. Codeforces 714C. Sonya and Queries Tire树

    C. Sonya and Queries time limit per test:1 second memory limit per test: 256 megabytes input:standar ...

  9. Educational Codeforces Round 2 B. Queries about less or equal elements 水题

    B. Queries about less or equal elements Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforc ...

随机推荐

  1. TZ_09_常用jQuery操作

    1.实现对chexkbox进行批量删除 checkbox属性 <td><input name="ids" type="checkbox" va ...

  2. 使用Spring Cache + Redis + Jackson Serializer缓存数据库查询结果中序列化问题的解决

    应用场景 我们希望通过缓存来减少对关系型数据库的查询次数,减轻数据库压力.在执行DAO类的select***(), query***()方法时,先从Redis中查询有没有缓存数据,如果有则直接从Red ...

  3. Nginx负载均衡反向代理

    http{ upstream test.com { server 118.118.66.88:8080; } server { listen 80; server_name www.test.com; ...

  4. 数据库完整性 ch.5

    数据库的完整性 是指 数据的正确性(correctness) 和 相容性 (compat-ability) 5.1 实体完整性 定义 对单属性码的说明有两种方法,一种是定义为表约束条件,一种是定义为列 ...

  5. oracle之FUNCTION拙见

    一.介绍 函数(Function)为一命名的存储程序,可带参数(有无均可),有返回值 函数和过程的结构类似,但必须有一个RETURN子句,用于返回函数值. 函数说明要指定函数名.返回值的类型,以及参数 ...

  6. Hdu 1498 二分匹配

    50 years, 50 colors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. php文件上传$_FILES数组格式

    <form action="" enctype="multipart/form-data" method="post"> < ...

  8. SDUT-3399_数据结构实验之排序二:交换排序

    数据结构实验之排序二:交换排序 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 冒泡排序和快速排序都是基于"交 ...

  9. 洛谷 P1266 速度限制 最短路+SPFA算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 P1266 速度限制 题目描述 在这个繁忙的社会中,我们往往不 ...

  10. Laravel 虚拟开发环境 Homestead

    简介 Laravel 致力于让你在 PHP 开发过程中更加轻松愉快,这其中也包括本地开发环境的搭建. Vagrant 提供了一种简单.优雅的方式来管理和配置虚拟机. Laravel Homestead ...