zoukankan      html  css  js  c++  java
  • 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
    ",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
    ");
                else printf("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;
    }
    
  • 相关阅读:
    Redis(八)理解内存
    Redis(七)Redis的噩梦:阻塞
    Redis(六)复制
    Redis(五)持久化
    笔试面试经典问题
    两个栈实现一个队列
    单链表相关操作
    我的笔记本
    10进制正整数转4位定长的36进制字符串
    微软2016校园招聘在线笔试之Magic Box
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10477742.html
Copyright © 2011-2022 走看看