zoukankan      html  css  js  c++  java
  • bzoj 3720: Gty的妹子树

    Description

    我曾在弦歌之中听过你,
    檀板声碎,半出折子戏。
    舞榭歌台被风吹去,
    岁月深处尚有余音一缕……
    Gty神(xian)犇(chong)从来不缺妹子……
    他来到了一棵妹子树下,发现每个妹子有一个美丽度……
    由于Gty很哲♂学,他只对美丽度大于某个值的妹子感兴趣。
    他想知道某个子树中美丽度大于k的妹子个数。
    某个妹子的美丽度可能发生变化……
    树上可能会出现一只新的妹子……
    维护一棵初始有n个节点的有根树(根节点为1),树上节点编号为1-n,每个点有一个权值wi。
    支持以下操作:
    0 u x 询问以u为根的子树中,严格大于x的值的个数。(u^=lastans,x^=lastans)
    1 u x 把u节点的权值改成x。(u^=lastans,x^=lastans)
    2 u x 添加一个编号为"当前树中节点数+1"的节点,其父节点为u,其权值为x。(u^=lastans,x^=lastans)
    最开始时lastans=0。

    解题报告

    对于这个题,直接以父亲所在块的(size)分块,如果父亲节点(size<B),直接把当前节点加入块中,否则新建一个块,(B)为设定的块的大小,对于插入做相同的判断即可.我们维护一个块内的节点的权值的单调性,每一次询问相同块内暴力找,如果遍历到了其他块直接二分块内即可,对于块与块之间可以建一个新图,方便遍历使用.
    对于修改操作,我们可以直接修改后sort,也可以利用单调性(O(B))插入,推荐后面一种方法.
    另外就是块大小的设定:本题中最优设定为 (sqrt{n*log}),可以简单证明:插入为(O(B)),询问为 (O(n*log(B)/B)),总复杂度为 (B+nlog(B)/B),根据均值不等式 (B)(sqrt{n*log})最优

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=70005,B=631;
    int n,fa[N],val[N],num=0,head[N],cnt=0,bel[N],Head[N],NUM=0,ans=0;
    struct edge{int nxt,to;}a[N<<1],e[N<<1];
    il void link(int x,int y){a[++num].nxt=head[x];a[num].to=y;head[x]=num;}
    il void lenk(int x,int y){e[++NUM].nxt=Head[x];e[NUM].to=y;Head[x]=NUM;}
    struct block{
        int c[B+5],size;
        il void insert(int x){
            size++;RG int i=size;
            for(i=size;i>=2 && x<=c[i-1];i--)c[i]=c[i-1];
            c[i]=x;
        }
        il void upd(int x,int y){
            RG int p=lower_bound(c+1,c+size+1,x)-c,i;
            for(i=p;i<size;i++)c[i]=c[i+1];
            for(i=size;i>=2 && y<=c[i-1];i--)c[i]=c[i-1];
            c[i]=y;
        }
        il int query(int x){
            int i=upper_bound(c+1,c+size+1,x)-c;
            return size-i+1;
        }
    }b[6005];
    il void dfs(RG int x){
        if(b[bel[fa[x]]].size<B)bel[x]=bel[fa[x]],b[bel[x]].insert(val[x]);
        else bel[x]=++cnt,b[cnt].insert(val[x]),lenk(bel[fa[x]],cnt);
        for(RG int i=head[x],u;i;i=a[i].nxt){
            u=a[i].to;if(u==fa[x])continue;
            fa[u]=x;dfs(u);
        }
    }
    il void btree(int x,int y){
        ans+=b[x].query(y);
        for(int i=Head[x],u;i;i=e[i].nxt){
            u=e[i].to;btree(u,y);
        }
    }
    il void qtree(int x,int y){
        if(val[x]>y)ans++;
        for(RG int i=head[x],u;i;i=a[i].nxt){
            u=a[i].to;if(u==fa[x])continue;
            if(bel[u]==bel[x])qtree(u,y);
            else btree(bel[u],y);
        }
    }
    void work()
    {
        int x,y;
        scanf("%d",&n);
        for(RG int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            link(x,y);link(y,x);
        }
        for(RG int i=1;i<=n;i++)scanf("%d",&val[i]);
        dfs(1);
        int m,flag;scanf("%d",&m);
        while(m--){
            scanf("%d%d%d",&flag,&x,&y);
            x^=ans;y^=ans;
            if(flag==0)ans=0,qtree(x,y),printf("%d
    ",ans);
            else if(flag==1){
                b[bel[x]].upd(val[x],y);
                val[x]=y;
            }
            else{
                fa[++n]=x;val[n]=y;link(x,n);link(n,x);
                if(b[bel[x]].size<B)bel[n]=bel[x],b[bel[x]].insert(y);
                else bel[n]=++cnt,lenk(bel[x],cnt),b[cnt].insert(y);
            }
        }
    }
    
    int main()
    {
        work();
        return 0;
    }
    
    
  • 相关阅读:
    一段简单的js让png24兼容ie6,单张图片有效
    “按需加载”的应用
    前端....
    项目小结
    Ember初始化实例
    Emberjs 分页
    Emberjs搜索
    promise链式
    Emberjs路由
    Emberjs笔记
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7654425.html
Copyright © 2011-2022 走看看