zoukankan      html  css  js  c++  java
  • HDU 6200 2017沈阳网络赛 树上区间更新,求和

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6200

    题意:给个图,有2种操作,一种是加一条无向边,二是查询u,v之间必须有的边的条数,所谓必须有的边就是对于u,v必须通过这条边才能到达。

    解法:一个很简单的想法,搞出图上的一颗树,然后剩下的边当成询问点队加到更新点集,每加入一个更新点对,直接把u,v区间的值置为0即可,查询就直接区间求和,可以直接树剖来维护,简单暴力,读入挂卡过。还有1个log的做法,可以用LCT维护(这个没写,口胡的)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+5;
    typedef long long LL;
    struct edge{
        int to,next;
        edge(){}
        edge(int to,int next):to(to),next(next){}
    }E[maxn*2];
    struct FastIO
    {
        static const int S = 1310720;
        int wpos;
        char wbuf[S];
        FastIO() : wpos(0) {}
        inline int xchar()
        {
            static char buf[S];
            static int len = 0, pos = 0;
            if (pos == len)
                pos = 0, len = fread(buf, 1, S, stdin);
            if (pos == len) return -1;
            return buf[pos ++];
        }
        inline int xuint()
        {
            int c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x;
        }
        inline int xint()
        {
            int s = 1, c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            if (c == '-') s = -1, c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x * s;
        }
        inline void xstring(char *s)
        {
            int c = xchar();
            while (c <= 32) c = xchar();
            for (; c > 32; c = xchar()) * s++ = c;
            *s = 0;
        }
        inline void wchar(int x)
        {
            if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
            wbuf[wpos ++] = x;
        }
        inline void wint(LL x)
        {
            if (x < 0) wchar('-'), x = -x;
            char s[24];
            int n = 0;
            while (x || !n) s[n ++] = '0' + x % 10, x /= 10;
            while (n--) wchar(s[n]);
        }
        inline void wstring(const char *s)
        {
            while (*s) wchar(*s++);
        }
        ~FastIO()
        {
            if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
        }
    } io;
    int n, m, head[maxn],edgecnt, tim;
    int sz[maxn], top[maxn], son[maxn], dep[maxn];
    int fa[maxn],tid[maxn];
    void init(){
        memset(head,-1,sizeof(head));
        memset(son,-1,sizeof(son));
        edgecnt=tim=0;
    }
    void add(int u,int v){
        E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
    }
    void dfs1(int u, int father, int d){
        dep[u]=d;
        fa[u]=father;
        sz[u]=1;
        for(int i=head[u]; i+1; i=E[i].next){
            int v=E[i].to;
            if(v!=father){
                dfs1(v,u,d+1);
                sz[u]+=sz[v];
                if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;
            }
        }
    }
    void dfs2(int u, int tp){
        top[u]=tp;
        tid[u]=++tim;
        if(son[u]==-1) return;
        dfs2(son[u],tp);
        for(int i=head[u];i+1;i=E[i].next){
            int v=E[i].to;
            if(v!=son[u]&&v!=fa[u])
                dfs2(v,v);
        }
    }
    namespace DSU{
        int fa1[maxn];
        void init1(){
            for(int i=1; i<maxn; i++) fa1[i]=i;
        }
        int find_set(int x){
            if(x==fa1[x]) return x;
            else return fa1[x] = find_set(fa1[x]);
        }
        bool union_set(int x, int y){
            x = find_set(x);
            y = find_set(y);
            if(x!=y){
                fa1[x]=y;
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    using namespace DSU;
    namespace SegmentTree{
        int sum[maxn<<2], lazy[maxn<<2];
        void pushup(int rt){
            sum[rt]=sum[rt*2]+sum[rt*2+1];
        }
        void pushdown(int rt){
            if(lazy[rt]){
                lazy[rt*2]=lazy[rt];
                lazy[rt*2+1]=lazy[rt];
                sum[rt*2]=sum[rt*2+1]=0;
                lazy[rt]=0;
            }
        }
        void build(int l, int r, int rt){
            lazy[rt] = 0;
            if(l == r){
                sum[rt] = l!=1;
                return;
            }
            int mid = (l+r)/2;
            build(l,mid,rt*2);
            build(mid+1,r,rt*2+1);
            pushup(rt);
        }
        void update(int L, int R, int l, int r, int rt){
            if(L<=l&&r<=R){
                lazy[rt]=1;
                sum[rt]=0;
                return;
            }
            pushdown(rt);
            int mid=(l+r)/2;
            if(L<=mid) update(L,R,l,mid,rt*2);
            if(mid<R) update(L,R,mid+1,r,rt*2+1);
            pushup(rt);
        }
        int query(int L, int R, int l, int r, int rt){
            if(L<=l&&r<=R) return sum[rt];
            int mid=(l+r)/2;
            pushdown(rt);
            int ret=0;
            if(L<=mid) ret+=query(L,R,l,mid,rt*2);
            if(mid<R) ret+=query(L,R,mid+1,r,rt*2+1);
            return ret;
        }
        void update(int u, int v){
            while(top[u]!=top[v]){
                if(dep[top[u]]<dep[top[v]]) swap(u,v);
                update(tid[top[u]], tid[u], 1, tim, 1);
                u = fa[top[u]];
            }
            if(u == v) return;
            if(dep[u]<dep[v]) swap(u,v);
            update(tid[v]+1,tid[u],1,tim,1);
        }
        int query(int u, int v){
            int ret=0;
            while(top[u]!=top[v]){
                if(dep[top[u]]<dep[top[v]]) swap(u,v);
                ret += query(tid[top[u]], tid[u], 1, tim, 1);
                u = fa[top[u]];
            }
            if(u==v) return ret;
            if(dep[u]<dep[v]) swap(u,v);
            ret += query(tid[v]+1,tid[u],1,tim,1);
            return ret;
        }
    }
    using namespace SegmentTree;
    int main()
    {
        int T,q,ks=0;
        T = io.xint();
        while(T--){
            printf("Case #%d:
    ", ++ks);
            n = io.xint();
            m = io.xint();
            init();
            init1();
            vector <pair<int, int> > G;
            for(int i=1; i<=m; i++){
                int u, v;
                u  = io.xint();
                v = io.xint();
                if(union_set(u,v)){
                    add(u, v);
                    add(v, u);
                }else{
                    G.emplace_back(u, v);
                }
            }
            dfs1(1,0,0);
            dfs2(1,1);
            build(1,n,1);
            for(auto &it:G){
                update(it.first,it.second);
            }
            q = io.xint();
            for(int i=1; i<=q; i++){
                int op,x,y;
                op = io.xint();
                x = io.xint();
                y = io.xint();
                if(op==1)
                    update(x, y);
                else{
                    printf("%d
    ", query(x,y));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    第一次Java测试及感触
    第七周学习
    第六周学习
    第5周学习
    第四周学习
    第三周学习
    浅略学习
    读完《大道至简》后的小感悟
    初识JAVA
    Java课后作业之石家庄地铁系统PSP表格20190403
  • 原文地址:https://www.cnblogs.com/spfa/p/7517609.html
Copyright © 2011-2022 走看看