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;
    }
    
  • 相关阅读:
    Best Time to Buy and Sell Stock III
    Valid Palindrome
    Longest Substring Without Repeating Characters
    Copy List with Random Pointer
    Add Two Numbers
    Recover Binary Search Tree
    Anagrams
    ZigZag Conversion
    Merge k Sorted Lists
    Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/spfa/p/7517609.html
Copyright © 2011-2022 走看看