zoukankan      html  css  js  c++  java
  • bzoj3720 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。

    Input

    输入第一行包括一个正整数n(1<=n<=30000),代表树上的初始节点数。
    接下来n-1行,每行2个整数u,v,为树上的一条无向边。
    任何时刻,树上的任何权值大于等于0,且两两不同。
    接下来1行,包括n个整数wi,表示初始时每个节点的权值。
    接下来1行,包括1个整数m(1<=m<=30000),表示操作总数。
    接下来m行,每行包括三个整数 op,u,v:
    op,u,v的含义见题目描述。
    保证题目涉及的所有数在int内。

    Output

    对每个op=0,输出一行,包括一个整数,意义见题目描述。

    Sample Input

    2
    1 2
    10 20
    1
    0 1 5

    Sample Output

    2

    正解:块状树。

    比较$simple$的块状树吧,不过挺容易写错的。。

    为了防止被卡,我直接设块的大小为$245$,然后直接按照$size$分块就行了。

    加入的话就看它父亲所在的块的大小是否大于$size$,如果大于就分一个新块。

    然后我们对于每个块,弄一个动态数组,把块内的权值排好序插进去。

    修改的话直接把整个块的动态数组清空,再重新排序加入就行了。

    查询的话我们还要把相邻的块连边,按照当前子树是否包括一个整块分类讨论一下就行了。。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <queue>
     10 #include <stack>
     11 #include <map>
     12 #include <set>
     13 #define inf (1<<30)
     14 #define N (500010)
     15 #define il inline
     16 #define RG register
     17 #define ll long long
     18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     19 
     20 using namespace std;
     21 
     22 struct edge{ int nt,to; }G[N],g[N];
     23 
     24 int Head[N],head[N],sz[N],st[N],top[N],fa[N],bl[N],a[N],w[N],T,n,m,num,Num,ans,cnt,block;
     25 
     26 vector <int> val[N];
     27 
     28 il int gi(){
     29     RG int x=0,q=1; RG char ch=getchar();
     30     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     31     if (ch=='-') q=-1,ch=getchar();
     32     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     33     return q*x;
     34 }
     35 
     36 il void insert(RG int from,RG int to){
     37     g[++num]=(edge){head[from],to},head[from]=num; return;
     38 }
     39 
     40 il void link(RG int from,RG int to){
     41     G[++Num]=(edge){Head[from],to},Head[from]=Num; return;
     42 }
     43 
     44 il void dfs1(RG int x,RG int p){
     45     RG int tp=T; fa[x]=p,st[++T]=x;
     46     for (RG int i=head[x];i;i=g[i].nt) if (g[i].to!=p) dfs1(g[i].to,x);
     47     if (T-tp>=block){
     48     ++cnt; while (T>tp) a[++sz[cnt]]=w[st[T]],bl[st[T--]]=cnt;
     49     sort(a+1,a+sz[cnt]+1); for (RG int j=1;j<=sz[cnt];++j) val[cnt].push_back(a[j]);
     50     }
     51     return;
     52 }
     53 
     54 il void dfs2(RG int x,RG int p){
     55     for (RG int i=head[x],v;i;i=g[i].nt){
     56     v=g[i].to; if (v==p) continue; dfs2(v,x);
     57     if (bl[x]!=bl[v]) top[bl[v]]=v,link(bl[x],bl[v]);
     58     }
     59     return;
     60 }
     61 
     62 il int find(RG int x,RG int k){
     63     RG int ans=0,l=0,r=sz[x]-1,mid;
     64     while (l<=r){
     65     mid=(l+r)>>1;
     66     if (val[x][mid]<=k) ans=mid+1,l=mid+1;
     67     else r=mid-1;
     68     }
     69     return sz[x]-ans;
     70 }
     71 
     72 il int calc1(RG int x,RG int k){
     73     RG int res=find(x,k);
     74     for (RG int i=Head[x];i;i=G[i].nt) res+=calc1(G[i].to,k);
     75     return res;
     76 }
     77 
     78 il int calc2(RG int x,RG int p,RG int k){
     79     RG int res=w[x]>k,v;
     80     for (RG int i=head[x];i;i=g[i].nt){
     81     v=g[i].to; if (v==p) continue;
     82     if (bl[x]==bl[v]) res+=calc2(v,x,k);
     83     else res+=calc1(bl[v],k);
     84     }
     85     return res;
     86 }
     87 
     88 il int query(RG int x,RG int k){
     89     RG int ans=0;
     90     if (top[bl[x]]==x) ans=calc1(bl[x],k); else ans=calc2(x,fa[x],k);
     91     return ans;
     92 }
     93 
     94 il void work(){
     95     n=gi(); for (RG int i=1,u,v;i<n;++i) u=gi(),v=gi(),insert(u,v),insert(v,u);
     96     for (RG int i=1;i<=n;++i) w[i]=gi(); block=245,dfs1(1,0);
     97     if (T){
     98     top[++cnt]=1; while (T) a[++sz[cnt]]=w[st[T]],bl[st[T--]]=cnt;
     99     sort(a+1,a+sz[cnt]+1); for (RG int i=1;i<=sz[cnt];++i) val[cnt].push_back(a[i]);
    100     }
    101     dfs2(1,0),m=gi();
    102     while (m--){
    103     RG int opt=gi(),x=gi()^ans,k=gi()^ans;
    104     if (!opt) ans=query(x,k),printf("%d
    ",ans);
    105     if (opt==1){
    106         RG int B=bl[x],ccnt=0;
    107         for (RG int i=0;i<sz[B];++i)
    108         if (val[B][i]!=w[x]) a[++ccnt]=val[B][i];
    109         a[++ccnt]=w[x]=k,val[B].clear(),sort(a+1,a+ccnt+1);
    110         for (RG int i=1;i<=ccnt;++i) val[B].push_back(a[i]);
    111     }
    112     if (opt==2){
    113         insert(x,++n),fa[n]=x,w[n]=k;
    114         if (sz[bl[x]]>=block){
    115         top[++cnt]=n,sz[cnt]=1,link(bl[x],cnt);
    116         bl[n]=cnt,val[cnt].push_back(k);
    117         } else{
    118         RG int B=bl[x],ccnt=0; bl[n]=B,a[++ccnt]=w[n];
    119         for (RG int i=0;i<sz[B];++i) a[++ccnt]=val[B][i];
    120         val[B].clear(),sort(a+1,a+(++sz[B])+1);
    121         for (RG int i=1;i<=sz[B];++i) val[B].push_back(a[i]);
    122         }
    123     }
    124     }
    125     return;
    126 }
    127 
    128 int main(){
    129     File("gty");
    130     work();
    131     return 0;
    132 }
  • 相关阅读:
    【转】Eclipse中查看jar包中的源码
    maven No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    Android问题-DelphiXE8新建AVD出现“no system images installed for this target”
    Android教程-DelphiXE Android自适应屏幕办法
    教程-在F9后提示内存错误,点击了乎略,之后怎么取消乎略?
    PC问题-该虚拟机似乎正在使用中
    PC问题-(仅供备用)取消磁盘的自动扫描
    Delphi实例-IdTCPServer和IdTCPClient的使用(支持文件发送)
    Android教程-DelphiXE Android的所有权限按照分类总结说明
    C++问题-UniqueAppObject.cpp(147): error C3861: “GUXClientInit”: 找不到标识符
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6951195.html
Copyright © 2011-2022 走看看