@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. ACdream 1108(莫队)

    题目链接 The kth number Time Limit: 12000/6000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) ...

  2. windows 标准错误重定向

    最近在windows上运行tensorflow的时候,出现很多stderr 的信息,干扰了正常的输出:所以我们需要使用操作把这些输出屏蔽: 参考链接:https://support.microsoft ...

  3. nginx在win系统下的安装配置与tomcat集成springmvc框架

    先来一个常用命令 验证配置是否正确: nginx -t 查看Nginx的版本号:nginx -V 启动Nginx:start nginx 快速停止或关闭Nginx:nginx -s stop 正常停止 ...

  4. python中str的常用方法汇总(1)

    a = 'strABC' # Strabc : 首字母大写,其他全部小写 b = a.capitalize() print(b) # STRABC : 全部大写 c = a.upper() print ...

  5. linux基础指令参数

    eth0,eth1,eth2--代表网卡一,网卡二,网卡三-- lo代表127.0.0.1,即localhost 参考: Linux命令:ifconfig 功能说明:显示或设置网络设备 语 法:ifc ...

  6. python自动化---各类发送邮件方法及其可能的错误

    一.发送文本邮件 可能的问题1.:需要注意,目前QQ邮箱来讲,不能收到完整的邮件,即有些内容不能显示,最好全部使用网易邮箱: 可能的问题2.:在以往的文本邮件发送中,只写了 msg = MIMETex ...

  7. 数据库安全 (ch.4)

    4.2.4 授权与回收 使用 Grant 授予权限 使用Revoke 回收权限 Grant [权限] ON *.. to * [with grant option] with grant option ...

  8. Linux下允许MySQL 授权远程连接

    1.mysql -u root -p   (root)用户名 2.mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'r ...

  9. 错觉-Info:让你难以置信的视错觉

    ylbtech-错觉-Info:让你难以置信的视错觉 1.返回顶部 1. 看下图:如果你看到舞者逆时针旋转说明你用左脑,如果看到顺时针旋转说明你用右脑思维. 据说这是耶鲁大学五年的研究成果.   下图 ...

  10. 最短路径问题 HDU - 3790 (Dijkstra算法 + 双重权值)

    参考:https://www.cnblogs.com/qiufeihai/archive/2012/03/15/2398455.html 最短路径问题 Time Limit: 2000/1000 MS ...