• bzoj 1146 [CTSC2008]网络管理Network


        很久之前写过 count on the tree。

        然后一直不懂树状数组是怎么套上这个主席树的。

        看了两小时发现它套的就是个权值线段树,

        看不出来可持久化在哪里。    

        因为动态开点所以空间nlog2n。

        树状数组维护dfs序,每个节点挂个线段树。

        为了省空间拿原树建了个主席树。

        

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define N 80005
      6 using namespace std;
      7 int n,q;
      8 int t[N];
      9 int head[N],ver[N*2],nxt[N*2],tot;
     10 int li[N*2],now[N*2],cnt;
     11 void add(int a,int b)
     12 {
     13     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
     14 }
     15 struct node 
     16 {
     17     int k,a,b;
     18 }qq[N];
     19 int zz,st[N],ed[N];
     20 int dep[N];
     21 int fa[N][18];
     22 void lca()
     23 {
     24     for(int i=1;i<=17;i++)
     25     for(int j=1;j<=n;j++)
     26     fa[j][i]=fa[fa[j][i-1]][i-1];
     27 }
     28 int lca(int x,int y)
     29 {
     30     if(dep[x]<dep[y])swap(x,y);
     31     for(int i=17;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
     32     if(x==y)return x;
     33     for(int i=17;i>=0;i--)
     34     {
     35         if(fa[x][i]!=fa[y][i])
     36         {
     37             x=fa[x][i];y=fa[y][i];
     38         }
     39     }
     40     return fa[x][0];
     41 }
     42 void dfs(int x,int f)
     43 {
     44     st[x]=++zz;
     45     for(int i=head[x];i;i=nxt[i])
     46     {
     47         if(ver[i]==f)continue;
     48         fa[ver[i]][0]=x;
     49         dep[ver[i]]=dep[x]+1;
     50         dfs(ver[i],x);
     51     }
     52     ed[x]=zz;
     53 }
     54 int root[N],rot[N];
     55 struct Node
     56 {
     57     int l,r,sum;
     58 }a[N*140];
     59 int num;
     60 
     61 void inrt(int x,int y,int l,int r,int pos)
     62 {
     63     if(l==r)
     64     {
     65         a[x].sum=a[y].sum+1;
     66         return ;
     67     }
     68     int mid=(l+r)>>1;
     69     if(pos<=mid)
     70     {
     71         if(!a[x].l)a[x].l=++num;
     72         a[x].r=a[y].r;
     73         inrt(a[x].l,a[y].l,l,mid,pos);
     74     }
     75     else
     76     {
     77         if(!a[x].r)a[x].r=++num;
     78         a[x].l=a[y].l;
     79         inrt(a[x].r,a[y].r,mid+1,r,pos);
     80     }
     81     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
     82 }
     83 void build()
     84 {
     85     for(int i=1;i<=n;i++)
     86     {
     87         if(!rot[i])rot[i]=++num;
     88         inrt(rot[i],rot[fa[i][0]],1,cnt,now[i]);
     89     }
     90 }
     91 void insert(int x,int l,int r,int pos,int z)
     92 {
     93     if(l==r)
     94     {
     95         a[x].sum+=z;return ;
     96     }
     97     int mid=(l+r)>>1;
     98     if(pos<=mid)
     99     {
    100         if(!a[x].l)a[x].l=++num;
    101         insert(a[x].l,l,mid,pos,z);
    102     }
    103     else
    104     {
    105         if(!a[x].r)a[x].r=++num;
    106         insert(a[x].r,mid+1,r,pos,z);
    107     }
    108     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
    109 }
    110 void ad(int x,int z,int la)
    111 {
    112     for(int i=x;i<=n;i+=(i&(-i)))
    113     {
    114         if(!root[i])root[i]=++num;
    115         insert(root[i],1,cnt,z,la);
    116     }
    117     return ;
    118 }
    119 int no[N][4];
    120 int t1,t2,t3,t4;
    121 int qur(int x,int y)
    122 {
    123     int as=0;
    124     for(int i=x;i;i-=(i&(-i)))
    125     {
    126         as+=a[a[no[i][y]].l].sum;
    127     }
    128     return as;
    129 }
    130 int qur(int l,int r,int kk,int r1,int r2,int r3,int r4)
    131 {
    132     if(l==r)
    133     {
    134         return l;
    135     }
    136     int mid=(l+r)>>1;
    137     int xx=a[a[r3].l].sum+a[a[r4].l].sum-a[a[r1].l].sum-a[a[r2].l].sum;
    138     xx+=qur(st[t1],0);xx+=qur(st[t2],1);
    139     xx-=qur(st[t3],2);xx-=qur(st[t4],3);
    140     if(xx>=kk)
    141     {
    142         for(int i=st[t1];i;i-=(i&(-i)))no[i][0]=a[no[i][0]].l;
    143         for(int i=st[t2];i;i-=(i&(-i)))no[i][1]=a[no[i][1]].l;
    144         for(int i=st[t3];i;i-=(i&(-i)))no[i][2]=a[no[i][2]].l;
    145         for(int i=st[t4];i;i-=(i&(-i)))no[i][3]=a[no[i][3]].l;
    146         return qur(l,mid,kk,a[r1].l,a[r2].l,a[r3].l,a[r4].l);
    147     }
    148     else
    149     {
    150         for(int i=st[t1];i;i-=(i&(-i)))no[i][0]=a[no[i][0]].r;
    151         for(int i=st[t2];i;i-=(i&(-i)))no[i][1]=a[no[i][1]].r;
    152         for(int i=st[t3];i;i-=(i&(-i)))no[i][2]=a[no[i][2]].r;
    153         for(int i=st[t4];i;i-=(i&(-i)))no[i][3]=a[no[i][3]].r;
    154         return qur(mid+1,r,kk-xx,a[r1].r,a[r2].r,a[r3].r,a[r4].r);
    155     }
    156 }
    157 int main()
    158 {
    159     scanf("%d%d",&n,&q);
    160     for(int i=1;i<=n;i++)scanf("%d",&t[i]),li[++cnt]=t[i];
    161     for(int i=1;i<n;i++)
    162     {
    163         scanf("%d%d",&t1,&t2);
    164         add(t1,t2);add(t2,t1);
    165     }
    166     for(int i=1;i<=q;i++)
    167     {
    168         scanf("%d%d%d",&qq[i].k,&qq[i].a,&qq[i].b);
    169         if(!qq[i].k)li[++cnt]=qq[i].b;
    170     }
    171     sort(li+1,li+cnt+1);
    172     cnt=unique(li+1,li+cnt+1)-li-1;
    173     for(int i=1;i<=n;i++)now[i]=lower_bound(li+1,li+cnt+1,t[i])-li;
    174     dep[1]=1;dfs(1,-1);
    175     lca();
    176     build();
    177     for(int i=1;i<=q;i++)
    178     {
    179         if(!qq[i].k)
    180         {
    181             ad(st[qq[i].a],now[qq[i].a],-1);
    182             if(ed[qq[i].a]!=zz)ad(ed[qq[i].a]+1,now[qq[i].a],1);
    183             now[qq[i].a]=lower_bound(li+1,li+cnt+1,qq[i].b)-li;
    184             ad(st[qq[i].a],now[qq[i].a],1);
    185             if(ed[qq[i].a]!=zz)ad(ed[qq[i].a]+1,now[qq[i].a],-1);
    186         }
    187         else
    188         {
    189             int tmp=lca(qq[i].a,qq[i].b);
    190             int yy=dep[qq[i].a]+dep[qq[i].b]-dep[tmp]*2+1;
    191             if(yy<qq[i].k)
    192             {
    193                 puts("invalid request!");
    194                 continue;
    195             }
    196             else
    197             {
    198                 yy=yy-qq[i].k+1;
    199                 for(int j=st[qq[i].a];j;j-=(j&(-j)))no[j][0]=root[j];
    200                 for(int j=st[qq[i].b];j;j-=(j&(-j)))no[j][1]=root[j];
    201                 for(int j=st[tmp];j;j-=(j&(-j)))no[j][2]=root[j];
    202                 for(int j=st[fa[tmp][0]];j;j-=(j&(-j)))no[j][3]=root[j];
    203                 t1=qq[i].a;t2=qq[i].b;t3=tmp;t4=fa[tmp][0];
    204                 int tp=qur(1,cnt,yy,rot[tmp],rot[fa[tmp][0]],rot[qq[i].a],rot[qq[i].b]);
    205                 printf("%d
    ",li[tp]);
    206             }
    207         }
    208     }
    209     return 0;
    210 }
  • 相关阅读:
    ViewPagerAdapter
    Android Touch事件传递机制详解
    android ANR产生原因和解决办法【转】
    Android 操作系统的内存回收机制(转载)
    android的程序运行数据存放在哪里?
    自定义RecyclerView.ItemDecoration,实现RecyclerView的分割线效果
    Android中 Bitmap和Drawable相互转换的方法
    android 存储图片到data目录和读取data目录下的图片
    多线程调用HttpWebRequest并发连接限制
    反射
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6259670.html
Copyright © 2020-2023  润新知