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;
}
posted @ 2019-03-06 19:57  风浔凌  阅读(219)  评论(0编辑  收藏  举报