zoukankan      html  css  js  c++  java
  • [bzoj1146]网络管理

    发现是链上的问题,所以树链剖分
    发现要查询第k大,因为第k大不支持合并,所以要二分答案
    二分答案后相当于询问一些区间内大于某数的数个数,直接线段树套平衡树即可
    时间复杂度$o(nlog^{4}_n)$(跟$o(n^{2})$有什么区别)可以卡过

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 100005
      4 #define L (k<<1)
      5 #define R (L+1)
      6 #define mid (l+r>>1)
      7 #define s(p) ch[k][p]
      8 struct ji{
      9     int nex,to;
     10 }edge[N<<1];
     11 int E,n,m,p,x,y,head[N],a[N],fa[N],sh[N],top[N],ma[N],id[N];
     12 int V,ro[N<<2],sz[N*50],sum[N*50],ra[N*50],v[N*50],ch[N*50][2];
     13 void add_edge(int x,int y){
     14     edge[E].nex=head[x];
     15     edge[E].to=y;
     16     head[x]=E++; 
     17 }
     18 void up(int k){
     19     sz[k]=sz[s(0)]+sz[s(1)]+sum[k];
     20 }
     21 void rotate(int &k,int x,int p){
     22     s(p)=ch[x][p^1];
     23     ch[x][p^1]=k;
     24     up(k);
     25     up(k=x);
     26 }
     27 void add(int &k,int x){
     28     if (!k){
     29         v[k=++V]=x;
     30         ra[k]=rand();
     31         sz[k]=0; 
     32     }
     33     sz[k]++;
     34     if (v[k]==x){
     35         sum[k]++;
     36         return;
     37     }
     38     bool p=(v[k]<x);
     39     add(s(p),x);
     40     if (ra[k]>ra[s(p)])rotate(k,s(p),p);
     41 }
     42 void del(int &k,int x){
     43     sz[k]--;
     44     if (v[k]==x){
     45         if (--sum[k])return;
     46         sum[k]++;
     47         if (s(0)*s(1)==0)k=s(0)+s(1);
     48         else{
     49             bool p=(ra[s(0)]>ra[s(1)]);
     50             rotate(k,s(p),p);
     51             del(k,x);
     52         }
     53         return;
     54     }
     55     del(s(v[k]<x),x);
     56 }
     57 int query(int k,int x){
     58     if (!k)return 0;
     59     if (v[k]==x)return sum[k]+sz[s(1)];
     60     bool p=(v[k]<x);
     61     return query(s(p),x)+(p^1)*(sum[k]+sz[s(1)]);
     62 }
     63 void update(int k,int l,int r,int x,int y,int z){
     64     if (y!=-1)del(ro[k],y);
     65     add(ro[k],z);
     66     if (l==r)return;
     67     if (x<=mid)update(L,l,mid,x,y,z);
     68     else update(R,mid+1,r,x,y,z);
     69 }
     70 int query(int k,int l,int r,int x,int y,int z){
     71     if ((l>y)||(x>r))return 0;
     72     if ((x<=l)&&(r<=y))return query(ro[k],z);
     73     return query(L,l,mid,x,y,z)+query(R,mid+1,r,x,y,z);
     74 }
     75 void dfs(int k,int f,int s){
     76     fa[k]=f;
     77     sh[k]=s;
     78     sz[k]=1;
     79     for(int i=head[k];i!=-1;i=edge[i].nex)
     80         if (edge[i].to!=f){
     81             dfs(edge[i].to,k,s+1);
     82             sz[k]+=sz[edge[i].to];
     83             if (sz[ma[k]]<sz[edge[i].to])ma[k]=edge[i].to;
     84         }
     85 }
     86 void dfs2(int k,int t){
     87     top[k]=t;
     88     id[k]=++x;
     89     update(1,1,n,x,-1,a[k]);
     90     if (ma[k])dfs2(ma[k],t);
     91     for(int i=head[k];i!=-1;i=edge[i].nex)
     92         if ((edge[i].to!=fa[k])&&(edge[i].to!=ma[k]))dfs2(edge[i].to,edge[i].to);
     93 }
     94 int query(int x,int y,int z){
     95     int ans=0;
     96     while (top[x]!=top[y]){
     97         if (sh[top[x]]<sh[top[y]])swap(x,y);
     98         ans+=query(1,1,n,id[top[x]],id[x],z);
     99         x=fa[top[x]];
    100     }
    101     if (id[x]>id[y])swap(x,y);
    102     return ans+query(1,1,n,id[x],id[y],z);
    103 }
    104 int find(){
    105     int l=0,r=100000000;
    106     while (l<r){
    107         int m=(l+r+1>>1);
    108         if (query(x,y,m)>=p)l=m;
    109         else r=m-1;
    110     }
    111     return l;
    112 }
    113 int main(){
    114     srand(time(0));
    115     scanf("%d%d",&n,&m);
    116     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    117     memset(head,-1,sizeof(head));
    118     for(int i=1;i<n;i++){
    119         scanf("%d%d",&x,&y);
    120         add_edge(x,y);
    121         add_edge(y,x);
    122     }
    123     dfs(1,0,0);
    124     x=0;
    125     dfs2(1,1);
    126     for(int i=1;i<=m;i++){
    127         scanf("%d%d%d",&p,&x,&y);
    128         if (!p){
    129             update(1,1,n,id[x],a[x],y);
    130             a[x]=y;
    131             continue;
    132         }
    133         if (query(x,y,0)<p)printf("invalid request!\n");
    134         else printf("%d\n",find());
    135     }
    136 }
    View Code
  • 相关阅读:
    css3学习 之 css选择器(结构性伪类选择器)
    flash如何实现Enumeration
    带参数的正则匹配
    css学习记录(overflow:hidden)
    JavaScript的函数
    HTML5实现网站在windows8中的贴靠
    Modernizr 让网站进行优雅降级
    ASP.NET Web API教程(三) 增删改
    Compat Inspector 微软内部使用的兼容性检测工具
    Javascript 高级手势
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11337632.html
Copyright © 2011-2022 走看看