[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

 

posted @ 2019-08-12 07:56  PYWBKTDA  阅读(133)  评论(0编辑  收藏  举报