【CF1217F】Forced Online Queries Problem
题意
动态图连通性,加密方式为 \((x+l-1)\bmod n +1\) (\(l=[上一次询问的两点连通]\))。
点数 \(n\),操作数 \(m\) \(\le 2\times 10^5\)。
Solution
容易发现这是一个假的强制在线—— \(l\) 的取值只有 \(0\) 和 \(1\) 两种,所以总共的操作种数不超过 \(2\times m\)。
于是我们可以考虑采用离线解决本题的思路,我们考虑线段树分治+可撤销并查集。
与离线不同的是,我们需要动态在线段树上添加节点。
具体而言,我们维护每条边的时间区间,每遍历到一个叶子结点上的修改,就维护对应边的时间区间,同时在线段树上进行插入。
code
#include<bits/stdc++.h>
using namespace std;
namespace io {
const int SIZE=(1<<21)+1;
char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];
#define gc()(iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
inline int gi (){ int x;
for(c=gc();c<'0'||c>'9';c=gc());
for(x=0;c<='9'&&c>='0';c=gc()) x=(x<<1)+(x<<3)+(c&15); return x;
}
} using io::gi;
const int N=2e5+5;
typedef pair<int,int> pr;
struct query
{
int op,x0,y0,x1,y1;
bool vis[2];
pr nxt0,nxt1;
} q[N];
vector<pr> st[N<<2];
int n,m,f[N],rk[N],stk[N],tp,lst;
map<pr,int> mp; int mid; pr pre[N<<1];
#define lx (x<<1)
#define rx (x<<1|1)
int findset(int u)
{
return f[u]?findset(f[u]):u;
}
void unionset(int u, int v)
{
u=findset(u),v=findset(v);
if(u!=v)
{
if (rk[u]<rk[v]) swap(u,v);
f[v]=u,rk[u]+=rk[v];
stk[++tp]=v;
}
}
void update(int x, int l, int r, int sl, int sr, pr w)
{
if(sl>sr) return ;
if(sl<=l&&r<=sr)
{
st[x].push_back(w);
return ;
}
int mid=l+r>>1;
if(sl<=mid) update(lx,l,mid,sl,sr,w);
if(sr>mid) update(rx,mid+1,r,sl,sr,w);
}
void solve(int x, int l, int r)
{
int now=tp;
for(auto i:st[x]) unionset(i.first,i.second);
if(l==r)
{
int nu=q[l].x0,nv=q[l].y0,lu=q[l].x1,lv=q[l].y1,nvis=q[l].vis[0],lvis=q[l].vis[1],r=0;
pr nnxt=q[l].nxt0,lnxt=q[l].nxt1;
if(lst) swap(nu,lu),swap(nv,lv),swap(nvis,lvis),swap(nnxt,lnxt),r=1;
if(q[l].op==2)
printf("%d",lst=(findset(nu)==findset(nv)));
else
{
if(!nvis)
{
update(1,1,m,l+1,nnxt.first-1,make_pair(nu,nv));
q[nnxt.first].vis[nnxt.second]=true;
}
if(lvis)
{
update(1,1,m,l+1,lnxt.first-1,make_pair(lu,lv));
q[lnxt.first].vis[lnxt.second]=true;
}
}
}
else
{
int mid=l+r>>1;
solve(lx,l,mid),solve(rx,mid+1,r);
}
for(;tp>now;--tp) rk[f[stk[tp]]]-=rk[stk[tp]],f[stk[tp]]=0;
}
int main()
{
n=gi(),m=gi();
for(int i=1;i<=n;++i) rk[i]=1;
for(int i=1;i<=m;++i)
{
q[i].op=gi(),q[i].x0=gi(),q[i].y0=gi();
if(q[i].x0>q[i].y0) swap(q[i].x0,q[i].y0);
q[i].x1=q[i].x0%n+1,q[i].y1=q[i].y0%n+1;
if(q[i].x1>q[i].y1) swap(q[i].x1,q[i].y1);
}
for(int i=m;i;--i)
{
if(q[i].op==2) continue;
int tid=mp[make_pair(q[i].x0,q[i].y0)];
if(!tid) q[i].nxt0=make_pair(m+1,0),tid=mp[make_pair(q[i].x0,q[i].y0)]=++mid;
else q[i].nxt0=pre[tid];
if(q[i].op==1) pre[tid]=make_pair(i,0);
tid=mp[make_pair(q[i].x1,q[i].y1)];
if(!tid) q[i].nxt1=make_pair(m+1,0),tid=mp[make_pair(q[i].x1,q[i].y1)]=++mid;
else q[i].nxt1=pre[tid];
pre[tid]=make_pair(i,1);
}
solve(1,1,m);
}
【CF1217F】Forced Online Queries Problem的更多相关文章
- 【BZOJ3489】A simple rmq problem(KD-Tree)
[BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...
- 【CF903G】Yet Another Maxflow Problem 线段树
[CF903G]Yet Another Maxflow Problem 题意:一张图分为两部分,左边有n个点A,右边有m个点B,所有Ai->Ai+1有边,所有Bi->Bi+1有边,某些Ai ...
- 【CF710F】String Set Queries(二进制分组,AC自动机)
[CF710F]String Set Queries(二进制分组,AC自动机) 题面 洛谷 CF 翻译: 你有一个字符集合\(D\),初始为空, 有三种操作: 往\(D\)中加入一个串:从\(D\)中 ...
- 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)
[CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...
- 【BZOJ3489】A simple rmq problem
[BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...
- 【BZOJ3489】A simple rmq problem kd-tree
[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...
- 【题解】CF986E Prince's Problem(树上差分+数论性质)
[题解]CF986E Prince's Problem(树上差分+数论性质) 题目大意: 给定你一棵树,有点权\(val_i\le 10^7\).现在有\(m\)组询问给定参数\(x,y,w\)问你对 ...
- 【动态规划】Codeforces 706C Hard problem
题目链接: http://codeforces.com/contest/706/problem/C 题目大意: n(2 ≤ n ≤ 100 000)个字符串(长度不超过100000),翻转费用为Ci( ...
- 【BZOJ】1700: [Usaco2007 Jan]Problem Solving 解题
[题意]给定n道题,每月末发放工资m,要求从1解到n,每道题需要在当月初付费ai,下月初付费bi,多道题可以安排在同月,求最少月数. [算法]DP [题解]参考自:[bzoj1700]Problem ...
随机推荐
- TC301A芯片做的一种人体接近感应方案
基于TC301A芯片做的一种人体接近感应方案,此方案的原理是通过检测电容的变化量来检测人体的有无,此方案设计原理简单,使用方便,容易操作,成本较低.设计方案如下:可根据原理图做pcb板子,如图芯片的五 ...
- HDU1875 畅通工程再续
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全 ...
- C++ STL之映射map的使⽤
写在最前面:本文摘录于柳神笔记: map 是键值对,⽐如⼀个⼈名对应⼀个学号,就可以定义⼀个字符串 string 类型的⼈名为“键”,学 号 int 类型为“值”,如 map<string, i ...
- Pipenv & 虚拟环境
本教程将引导您完成安装和使用 Python 包. 它将向您展示如何安装和使用必要的工具,并就最佳做法做出强烈推荐.请记住, Python 用于许多不同的目的.准确地说,您希望如何管理依赖项可能会根据 ...
- 开关机安全控制!(设置进入bois的密码)
1.调整 BOIS 引导设置(1)将第一引导设备设为当前系统所在硬盘 (2)设置管理员密码 (3)进入bois后如图所示需输入bols密码才能登入
- Ajax案例
展示页面jsp: <%@ page language="java" contentType="text/html; charset=utf-8" pa ...
- 模块学习--random
1 随机一个0-1之间float >>> random.random() 0.82544262519395 >>> random.random() 0.114854 ...
- pta 7-1 找出不是两个数组共有的元素
给定两个整型数组,本题要求找出不是两者共有的元素. 输入格式: 输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔. 输出格式: 在一行中按照数字给出的顺序 ...
- sql数据库的基本操作
命令行 1.显示当前数据库服务器中的数据库列表:mysql> SHOW DATABASES;2.建立数据库:mysql> CREATE DATABASE 库名;3.建立数据表:mysql& ...
- Py西游攻关之基础数据类型(六)-文件操作
Py西游攻关之基础数据类型 - Yuan先生 https://www.cnblogs.com/yuanchenqi/articles/5782764.html 九 文件操作 9.1 对文件操作流程 打 ...