码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 4551: [Tjoi2016&Heoi2016]树

时间:2017-03-24 00:42:07      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:c++   script   get   scanf   cto   lin   amp   lang   time   

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\n",Tree::Query(x));
        }
    }return 0;
}

  

BZOJ 4551: [Tjoi2016&Heoi2016]树

标签:c++   script   get   scanf   cto   lin   amp   lang   time   

原文地址:http://www.cnblogs.com/beiyuoi/p/6607605.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!