首页 > 代码库 > BZOJ 4551: [Tjoi2016&Heoi2016]树

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

  

BZOJ 4551: [Tjoi2016&Heoi2016]树