• [bzoj3720]Gty的妹子树


    这道题还有一种分块的做法:每当发现当前子树中有K个点,就将这K个点合在一起,然后把每个块内的节点权值排序(虽然这个算法并没有保证块的个数,但是由于数(shen)(qi)(hai)(luo),所以不妨设为n/K)。

    操作0:对于每一个块暴力查询(构建一颗虚树),然后对根所在块暴力,时间复杂度o(K+n/K)

    操作1:暴力修改该权值并排序(可以插入,也可以直接sort

    操作2:当添加节点父亲所在块节点个数不到K,直接加入该块,否则单独成块,注意维护节点信息。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define siz 300
     4 #define N 100005
     5 struct ji{
     6     int nex,to;
     7 }edge[N<<1];
     8 int E,n,m,x,y,s,p,z,ans,head[2][N],bl[N],f[N],w[N],se[N/3][siz+10];
     9 void add(int x,int y,int p){
    10     edge[E].nex=head[p][x];
    11     edge[E].to=y;
    12     head[p][x]=E++;
    13 }
    14 void dfs(int k,int fa){
    15     f[k]=fa;
    16     if (se[bl[fa]][0]==siz)add(bl[fa],++s,1);
    17     bl[k]=s;
    18     se[s][++se[s][0]]=w[k];
    19     for(int i=head[0][k];i!=-1;i=edge[i].nex)
    20         if (edge[i].to!=fa)dfs(edge[i].to,k);
    21 }
    22 void dfs2(int k){
    23     ans+=se[k]+se[k][0]+1-upper_bound(se[k]+1,se[k]+se[k][0]+1,y);
    24     for(int i=head[1][k];i!=-1;i=edge[i].nex)dfs2(edge[i].to);
    25 }
    26 void calc(int k,int fa,int p){
    27     if (bl[k]!=p){
    28         dfs2(bl[k]);
    29         return;
    30     }
    31     if (w[k]>y)ans++;
    32     for(int i=head[0][k];i!=-1;i=edge[i].nex)
    33         if (edge[i].to!=fa)calc(edge[i].to,k,p);
    34 }
    35 int main(){
    36     scanf("%d",&n);
    37     memset(head,-1,sizeof(head));
    38     for(int i=1;i<n;i++){
    39         scanf("%d%d",&x,&y);
    40         add(x,y,0);
    41         add(y,x,0);
    42     }
    43     s++;
    44     for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    45     dfs(1,0);
    46     for(int i=1;i<=s;i++)sort(se[i]+1,se[i]+se[i][0]+1);
    47     scanf("%d",&m);
    48     for(int i=1;i<=m;i++){
    49         scanf("%d%d%d",&p,&x,&y);
    50         x^=ans;
    51         y^=ans;
    52         if (!p){
    53             ans=0;
    54             calc(x,f[x],bl[x]);
    55             printf("%d\n",ans);
    56         }
    57         if (p==1){
    58             z=bl[x];
    59             se[z][lower_bound(se[z]+1,se[z]+se[z][0]+1,w[x])-se[z]]=y;
    60             sort(se[z]+1,se[z]+se[z][0]+1);
    61             w[x]=y;
    62         }
    63         if (p==2){
    64             w[++n]=y;
    65             add(x,n,0);
    66             f[n]=x;
    67             if (se[bl[x]][0]==siz)bl[n]=++s;
    68             else bl[n]=bl[x];
    69             z=bl[n];
    70             se[z][++se[z][0]]=y;
    71             if (z!=bl[x])add(bl[x],z,1);
    72             sort(se[z]+1,se[z]+se[z][0]+1);
    73         }
    74     }
    75 }
    View Code
  • 相关阅读:
    mongoDb学习以及spring管理 (包括百度云配置)
    Python循环嵌套
    Web应用功能测试测试点
    二维数组联通子数组
    二维数组最大子数组问题
    环一维数组最大子数组问题
    电梯调研
    最大子数组问题
    小学生题目
    3.13题目思路
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249872.html
Copyright © 2020-2023  润新知