zoukankan      html  css  js  c++  java
  • BZOJ4551

    Portal

    Description

    给出一棵(n(nleq10^5))个点的以(1)为根的有根树,进行(Q(Qleq10^5))次操作:

    • 标记一个点(x)
    • 询问(x)的祖先中(包括(x)),距(x)最近的被标记的点。

    Solution

    用lct搞一搞就行啦。标记点(x)splay(x),询问时access(x)后求最深的被标记点即可。

    时间复杂度(O(Qlogn))

    Code

    //树
    #include <cstdio>
    inline char gc()
    {
        static char now[1<<16],*s,*t;
        if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
        return *s++;
    }
    inline int read()
    {
        int x=0; char ch=gc();
        while(ch<'0'||'9'<ch) ch=gc();
        while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
        return x;
    }
    int const N=1e5+10;
    int n,Q;
    int cnt,h[N];
    struct edge{int v,nxt;} ed[N<<1];
    inline void edAdd(int u,int v)
    {
        cnt++; ed[cnt].v=v,ed[cnt].nxt=h[u],h[u]=cnt;
        cnt++; ed[cnt].v=u,ed[cnt].nxt=h[v],h[v]=cnt;
    }
    int fa[N],ch[N][2]; int sum[N],val[N];
    void bldTree(int u)
    {
        for(int i=h[u];i;i=ed[i].nxt)
            if(ed[i].v!=fa[u]) fa[ed[i].v]=u,bldTree(ed[i].v);
    }
    inline int wh(int p) {return p==ch[fa[p]][1];}
    inline int notRt(int p) {return p==ch[fa[p]][wh(p)];}
    inline void update(int p) {sum[p]=sum[ch[p][0]]+val[p]+sum[ch[p][1]];}
    inline void rotate(int p)
    {
        int q=fa[p],r=fa[q],w=wh(p);
        fa[p]=r; if(notRt(q)) ch[r][wh(q)]=p;
        fa[ch[q][w]=ch[p][w^1]]=q;
        fa[ch[p][w^1]=q]=p;
        update(q),update(p);
    }
    void splay(int p)
    {
        for(int q=fa[p];notRt(p);rotate(p),q=fa[p]) if(notRt(q)) rotate(wh(p)^wh(q)?p:q);
    }
    int rnk(int rt,int x)
    {
        int p=rt;
        while(true)
            if(x<=sum[ch[p][0]]) p=ch[p][0];
            else if(x<=sum[ch[p][0]]+val[p]) return p;
            else x-=sum[ch[p][0]]+val[p],p=ch[p][1];
    }
    void access(int p) {for(int q=0;p;q=p,p=fa[p]) splay(p),ch[p][1]=q,update(p);}
    int query(int p) {access(p),splay(p); return rnk(p,sum[p]);}
    int main()
    {
        n=read(),Q=read();
        for(int i=1;i<=n-1;i++) edAdd(read(),read());
        fa[1]=0,bldTree(1); val[1]=1,update(1);
        for(int i=1;i<=Q;i++)
        {
            char opt=gc(); while(opt!='C'&&opt!='Q') opt=gc();
            int u=read();
            if(opt=='C') val[u]=1,update(u),splay(u);
            else printf("%d
    ",query(u));
        }
        return 0;
    }
    

    P.S.

    这题原数据水到暴力AC...没错就是每次跳fa

  • 相关阅读:
    Java Program to Calculate Standard Deviation
    Basic JavaScript: Counting Cards
    MacBook Pro jdk Installation、Update、Delete
    How to Download and Install Oracle JAVA 8 on Ubuntu 18.04/16.04 LTS
    9扩大你的词汇量:字体和颜色样式
    8添加一些样式:开始学习CSS
    7添加一个“X”到HTML:转到XHTML
    6严格的HTML:遵循标准,合乎规范
    5认识媒体:给网页添加图像
    4Web镇之旅:开始链接
  • 原文地址:https://www.cnblogs.com/VisJiao/p/BZOJ4551.html
Copyright © 2011-2022 走看看