SHOI2008 堵塞的交通
题目链接:戳我
线段树在线维护动态图连通性
有一篇超级棒的线段树+大力分类讨论的题解!戳我
可是我还是不会写这个做法qwqwqwq
这里提供线段树分治的写法。感觉比较不需要智商,就是跑的有点慢了。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<vector>
#define MAXN 200010
using namespace std;
int n,m,cnt;
int fa[MAXN],siz[MAXN];
char kkk[10];
struct Node{int x,y;};
struct Que{int op,x,y;}q[MAXN];
struct Seg
{
int l,r;
vector<int>v;
}t[MAXN<<2];
stack<Node>s;
map<pair<int,int>,int>tim;
inline int ls(int x) {return x<<1;}
inline int rs(int x) {return x<<1|1;}
inline int id(int x,int y){return (x-1)*n+y;}
inline int find(int x){return fa[x]==x?x:find(fa[x]);}
inline void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
}
inline void merge(int x,int y)
{
x=find(x),y=find(y);
if(x==y) return;
if(siz[x]>siz[y]) swap(x,y);
fa[x]=y;
s.push((Node){x,y});
siz[y]+=siz[x];
}
inline void del(int x)
{
while((int)s.size()>x)
{
Node cur=s.top(); s.pop();
siz[cur.y]-=siz[fa[cur.x]=cur.x];
}
}
inline void insert(int x,int ll,int rr,int k)
{
int l=t[x].l,r=t[x].r;
if(ll<=l&&r<=rr)
{
t[x].v.push_back(k);
//printf("l=%d r=%d ll=%d rr=%d k=%d\n",l,r,ll,rr,k);
return;
}
int mid=(l+r)>>1;
if(ll<=mid) insert(ls(x),ll,rr,k);
if(mid<rr) insert(rs(x),ll,rr,k);
}
inline void solve(int x)
{
int cur=s.size();
for(int i=0,len=t[x].v.size();i<len;i++)
merge(q[t[x].v[i]].x,q[t[x].v[i]].y);
if(t[x].l==t[x].r)
{
if(q[t[x].l].op==2)
{
if(find(q[t[x].l].x)==find(q[t[x].l].y))
printf("Y\n");
else printf("N\n");
}
}
else solve(ls(x)),solve(rs(x));
del(cur);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce1.in","r",stdin);
freopen("ce.out","w",stdout);
#endif
scanf("%d",&n);
for(int i=1;i<=2;i++)
for(int j=1;j<=n;j++)
fa[id(i,j)]=id(i,j),siz[id(i,j)]=1;
build(1,1,100010);
scanf("%s",kkk);
int x1,x2,y1,y2;
while(kkk[0]!='E')
{
++cnt;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int op;
//if(y1>y2) swap(y1,y2),swap(x1,y2);
int u=id(x1,y1),v=id(x2,y2);
if(u>v) swap(u,v);
if(kkk[0]=='O')
{
op=0;
tim[make_pair(u,v)]=cnt;
}
else if(kkk[0]=='C')
{
op=1;
insert(1,tim[make_pair(u,v)],cnt,cnt);
tim.erase(make_pair(u,v));
}
else op=2;
q[cnt]=(Que){op,u,v};
scanf("%s",kkk);
}
for(map<pair<int,int>,int>::iterator it=tim.begin();it!=tim.end();it++)
{
insert(1,it->second,cnt,it->second);
}
solve(1);
return 0;
}