标签:return mod 撤销 can getchar you oid lang ret
这个题第一眼是线段树分治吧。
但是这个题和大部分板子不同的是,这里询问不是全图连通性了,是两点的连通性。其实思路没什么大区别,还是要用可撤销并查集维护连通性,把边挂到线段树上相应的时间点上。
只是我们现在的询问不同了,我们可以模仿把边挂在线段树上的方式,把询问挂在单点上。每个时间点上最多有一次询问,由于线段树上的点是按时间顺序排列的,我们在遍历到这个点的时候,直接输出结果即可。
//Don‘t act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you‘ll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
#define pr pair<int,int>
using namespace std;
int read() {
char ch=getchar();
int f=1,x=0;
while(ch<‘0‘||ch>‘9‘) {
if(ch==‘-‘)
f=-1;
ch=getchar();
}
while(ch>=‘0‘&&ch<=‘9‘) {
x=x*10+ch-‘0‘;
ch=getchar();
}
return f*x;
}
const int MAXN=10000+10,MAXM=2e5+10;
int n,m,q,cnt,num;
stack<pr > stk;
int size[MAXN],father[MAXN];
vector<pr > edge[MAXM<<2];
vector<pr > qry[MAXM<<2];
set<pr > s;
map<pr,int > mp;
pr make_edge(int x,int y) {
return make_pair(min(x,y),max(x,y));
}
int find(int x) {
if(x!=father[x]) {
return find(father[x]);
}
return x;
}
void merge(pr s) {
int x=find(s.first);
int y=find(s.second);
if(x==y) {
stk.push(make_pair(-1,-1));
return ;
}
if(size[x]>size[y]) {
swap(x,y);
}
father[x]=y;
size[y]+=size[x];
stk.push(make_pair(x,y));
}
void del() {
int x=stk.top().first;
int y=stk.top().second;
stk.pop();
if(x==-1) {
return ;
}
father[x]=x;
size[y]-=size[x];
}
void modify(int l,int r,int p,int x,int y,pr s) {
if(x>y||r<x||y<l) {
return ;
}
if(x<=l&&r<=y) {
edge[p].push_back(s);
return ;
}
int mid=(l+r)>>1;
modify(l,mid,p<<1,x,y,s);
modify(mid+1,r,p<<1|1,x,y,s);
}
void modqry(int l,int r,int p,int x,int y,pr s) {
if(x>y||r<x||y<l) {
return ;
}
if(x<=l&&r<=y) {
qry[p].push_back(s);
//把询问挂到线段树上
return ;
}
int mid=(l+r)>>1;
modqry(l,mid,p<<1,x,y,s);
modqry(mid+1,r,p<<1|1,x,y,s);
}
void query(int l,int r,int p) {
int sz=edge[p].size();
for(int i=0;i<sz;i++) {
merge(edge[p][i]);
}
if(l==r) {
int qsz=qry[p].size();
//qsz的值域在 [0,1]。
for(int i=0;i<qsz;i++) {
if(find(qry[p][i].first)==find(qry[p][i].second)) {
puts("Yes");
}
else {
puts("No");
}
}
}
else {
int mid=(l+r)>>1;
query(l,mid,p<<1);
query(mid+1,r,p<<1|1);
}
while(sz--) {
del();
}
}
signed main() {
cin>>n;
for(int i=1;i<=n;i++) {
father[i]=i;
size[i]=1;
}
cin>>q;
for(int i=1;i<=q;i++) {
string c;
cin>>c;
int u,v;
u=read();
v=read();
if(c[0]==‘Q‘) {
modqry(1,q,1,i,i,make_pair(u,v));
}
if(c[0]==‘C‘) {
s.insert(make_edge(u,v));
mp[make_edge(u,v)]=i;
}
if(c[0]==‘D‘) {
modify(1,q,1,mp[make_edge(u,v)],i-1,make_edge(u,v));
mp[make_edge(u,v)]=0;
s.erase(make_edge(u,v));
}
}
for(set<pr >::iterator it=s.begin();it!=s.end();it++) {
modify(1,q,1,mp[*it],q,*it);
//还有些边没被删除要加进去
}
query(1,q,1);
return 0;
}
标签:return mod 撤销 can getchar you oid lang ret
原文地址:https://www.cnblogs.com/huayucaiji/p/LG2147.html