zoukankan      html  css  js  c++  java
  • BZOJ 3720: Gty的妹子树 [树上size分块]

    传送门

    题意: 一棵树,询问子树中权值大于$k$的节点个数,修改点权值,插入新点;强制在线


    一开始以为询问多少种不同的权值,那道CF的强制在线带修改版,直接吓哭

    然后发现看错了这不一道树上分块水题...

    用王室联邦分块的话需要维护每一个块$dfs$序最小值和最大值,并且插入操作会破坏原来的性质

    不如直接按$size$分块,根节点$size<block$就加入根,否则新建块

    $size$分块不能保证块的数量,可以被菊花图卡掉,然而本题没有所以就可以安心的写了

    每个块维护排序后的值

    查询操作,不完整的块(因为是$size$分块所以只有子树根所在块不完整)暴力,直接把块建一个图,每个整块二分

    修改维护有序,插入也维护有序;当然修改和插入后重新排序也可以

    复杂度 修改插入$O(S)$ 查询$O(S+frac{N}{S}logS)$

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int N=6e4+5, M=1e4+5, S=700;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int n,Q,a[N],op,u,x;
    struct edge{int v,ne;} e[N<<1];
    int cnt,h[N];
    inline void ins(int u,int v) {
        e[++cnt]=(edge){v,h[u]}; h[u]=cnt;
        e[++cnt]=(edge){u,h[v]}; h[v]=cnt;
    }
    
    struct meow{
        int a[S], size;
        inline void set() {sort(a+1, a+1+size);}
        inline int count(int v) {return size - (upper_bound(a+1, a+1+size, v) - a) + 1;}
        inline void push(int v) {a[++size]=v;}
        inline void replace(int x,int v) { 
            if(x==v) return;
            for(int i=1;i<=size;i++) if(a[i]==x) {
                if(v>x) while(i<size && v>a[i+1]) a[i]=a[i+1], i++;
                else while(i>1 && v<a[i-1]) a[i]=a[i-1], i--;
                a[i]=v; break;
            }
        }
        inline void insert(int v){
            int i; 
            for(i=1; i<=size && a[i]<v; i++) ;
            for(int j=size; j>=i; j--) a[j+1]=a[j];
            a[i]=v; size++;
        }
    }b[M];
    int m, pos[N], block;
    
    struct Graph4Block{
        struct edge{int v,ne;} e[M];
        int cnt,h[M];
        inline void ins(int u,int v) {
            e[++cnt]=(edge){v,h[u]}; h[u]=cnt;
        }
        int dfs(int u,int k) {
            int ans= b[u].count(k);
            for(int i=h[u];i;i=e[i].ne) ans+=dfs(e[i].v, k);
            return ans;
        }
    }G;
    
    int fa[N];
    void dfs(int u) {
        int p=pos[u]; 
        b[p].push(a[u]);
        for(int i=h[u];i;i=e[i].ne) 
            if(e[i].v!=fa[u]) {
                fa[e[i].v]=u;
                if(b[p].size < block) pos[e[i].v]=p;
                else pos[e[i].v]=++m, G.ins(p, m);
                dfs(e[i].v);
            }
    }
    
    struct Block{
        int dfs(int u,int k) {
            int ans= a[u]>k;
            for(int i=h[u];i;i=e[i].ne) 
                if(e[i].v!=fa[u]) {
                    if(pos[e[i].v] == pos[u]) ans+= dfs(e[i].v, k);
                    else ans+= G.dfs(pos[e[i].v], k);
                }
            return ans;
        }
        int Que(int u, int k) {return dfs(u, k);}
    
        void Cha(int u, int d) {b[pos[u]].replace(a[u], d); a[u]=d;}
    
        void Ins(int u, int d){
            a[++n]=d; ins(u, n); fa[n]=u; 
            int p=pos[u];
            if(b[p].size < block) pos[n]=p, b[p].insert(a[n]);
            else pos[n]=++m, b[m].push(a[n]), G.ins(p, m);
        }
    }B;
    int main() {
        freopen("in", "r", stdin);
        n=read();
        for(int i=1;i<n;i++) ins(read(), read() );
        for(int i=1;i<=n;i++) a[i]=read();
        block=pow(n, 0.6);
        pos[1]=++m; dfs(1); 
        for(int i=1;i<=m;i++) b[i].set();
    
        Q=read(); int lastans=0;
        for(int i=1;i<=Q;i++) {
            op=read(); 
            u=read()^lastans; x=read()^lastans; 
            if(op==0) lastans=B.Que(u, x), printf("%d
    ",lastans);
            else if(op==1) B.Cha(u, x);
            else B.Ins(u, x);
        }
    }
  • 相关阅读:
    bzoj 1098 [POI2007] 办公楼 biu
    「 Luogu P2574 」 XOR的艺术——线段树
    「 Luogu P2801 」 教主的魔法——分块
    Luogu P1438 无聊的数列
    「 Luogu P2420 」 让我们异或吧
    「 SPOJ GSS3 」 Can you answer these queries III
    「 HDOJ P2227 」 Find the nondecreasing subsequences
    「 HDOJ P3887 」 Counting Offspring
    一些性质及公式
    OI杂记
  • 原文地址:https://www.cnblogs.com/candy99/p/6576084.html
Copyright © 2011-2022 走看看