zoukankan      html  css  js  c++  java
  • BZOJ 4551: [Tjoi2016&Heoi2016]树

    Description

    一棵树有黑白点,求最近黑点祖先。

    Solution

    树链剖分。

    我居然敲了15min?

    Code

    /**************************************************************
        Problem: 4551
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:1972 ms
        Memory:11952 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define mpr make_pair
    #define x first
    #define y second
    #define debug(a) cout<<(#a)<<"="<<a<<" "
    //#define lc(o) ch[o][0]
    //#define rc(o) ch[o][1]
    #define lc (o<<1)
    #define rc (o<<1|1)
    #define mid ((l+r)>>1)
     
    typedef long long LL;
    typedef pair<int,int> pr;
    typedef vector<int> Vi;
    typedef vector<LL> Vl;
    typedef vector<string> Vs;
    const int N = 100500;
    const int M = N<<2;
    const int oo = 0x3fffffff;
    const LL  OO = 1e18;
     
    inline LL in(LL x=0,char ch=getchar(),int v=1) {
        while(ch>'9' || ch<'0') v=ch=='-'?-1:v,ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x*v;
    }
    /*end*/
     
    int n,q;
    int p[N],rp[N],mk[N];
     
    struct SegmentTree {
        int d[M];
         
        void Modify(int o,int l,int r,int x) {
            if(l==r) { d[o]=l;return; }
            if(x<=mid) Modify(lc,l,mid,x);
            else Modify(rc,mid+1,r,x);
            d[o]=max(d[lc],d[rc]);
        }
        int Query(int o,int l,int r,int L,int R) {
            if(L<=l && r<=R) return d[o];
            int res=0;
            if(L<=mid) res=max(res,Query(lc,l,mid,L,R));
            if(R>mid) res=max(res,Query(rc,mid+1,r,L,R));
            return res;
        }
    }py;
     
    namespace Tree {
        int cnt;
        int d[N],f[N],top[N],sz[N],sn[N];
        vector<int> g[N];
         
        void AddEdge(int u,int v) { g[u].push_back(v),g[v].push_back(u); }
        void DFS1(int u,int fa) {
            d[u]=d[fa]+1,sz[u]=1,sn[u]=0;
            for(int i=0,v;i<(int)g[u].size();i++) if((v=g[u][i])!=fa) {
                DFS1(v,u),sz[u]+=sz[v],f[v]=u;
                if(!sn[u] || sz[sn[u]]<sz[v]) sn[u]=v;
            }
        }
        void DFS2(int u,int fa,int tp) {
            p[u]=++cnt,rp[cnt]=u,top[u]=tp;
            if(sn[u]) DFS2(sn[u],u,tp);
            for(int i=0,v;i<(int)g[u].size();i++) if((v=g[u][i])!=fa && v!=sn[u]) 
                DFS2(v,u,v);
        }
        void init() {
            DFS1(1,1),DFS2(1,1,1);
            py.Modify(1,1,n,1);
            mk[1]=1;
        }
        int Query(int u) {
            int f1=top[u],res=0;
            for(;u;) {
                res=py.Query(1,1,n,p[f1],p[u]);
                if(res) return rp[res];
                u=f[f1],f1=top[u];
            }return 1;
        }
    }
     
    int main() {
        n=in(),q=in();
        for(int i=1;i<n;i++) {
            int x=in(),y=in();
            Tree::AddEdge(x,y);
        }
        Tree::init();
        for(int i=1;i<=q;i++) {
            char opt[15];int x;
            scanf("%s",opt);
            if(opt[0]=='C') {
                x=in();
                if(!mk[x]) mk[x]=1,py.Modify(1,1,n,p[x]);
            } else {
                x=in();
                printf("%d
    ",Tree::Query(x));
            }
        }return 0;
    }
    

      

  • 相关阅读:
    P2602 [ZJOI2010]数字计数
    P2657 [SCOI2009] windy 数
    Gym
    B
    Problem E The League of Sequence Designers
    C. Vladik and fractions
    hdu6069
    hdu 6096
    30道经典面试题,靠它我在一线拿到了20k的前端开发工程师岗位
    【面经分享】互联网寒冬,7面阿里,终获Offer!
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6607605.html
Copyright © 2011-2022 走看看