bzoj1146 [CTSC2008]网络管理Network (树上带修改主席树)

1146: [CTSC2008]网络管理Network

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 4070  Solved: 1229
[Submit][Status][Discuss]

Description

  M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络。该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信。 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略。但是由于路由器老化,在这些路由器上进行数据交换会带来很大的延迟。而两个路由器之间的通信延迟时间则与这两个路由器通信路径上所有路由器中最大的交换延迟时间有关。作为M公司网络部门的一名实习员工,现在要求你编写一个简单的程序来监视公司的网络状况。该程序能够随时更新网络状况的变化信息(路由器数据交换延迟时间的变化),并且根据询问给出两个路由器通信路径上延迟第k大的路由器的延迟时间。【任务】 你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们可能是: 1. 由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。 2. 查询某两个路由器a和b之间的路径上延迟第k大的路由器的延迟时间。

Input

  第一行为两个整数N和Q,分别表示路由器总数和询问的总数。第二行有N个整数,第i个数表示编号为i的路由器初始的数据延迟时间Ti。紧接着N-1行,每行包含两个整数x和y。表示有一条光缆连接路由器x和路由器y。紧接着是Q行,每行三个整数k、a、b。如果k=0,则表示路由器a的状态发生了变化,它的数据交换延迟时间由Ta变为b。如果k>0,则表示询问a到b的路径上所经过的所有路由器(包括a和b)中延迟第k大的路由器的延迟时间。注意N,Q<=80000,任意一个路由器在任何时刻都满足延迟时间小于10^8。对于所有询问满足0<=K<=N

Output

  对于每一个第二种询问(k>0),输出一行。包含一个整数为相应的延迟时间。如果路径上的路由器不足k个,则输出信息“invalid request!”(全部小写不包含引号,两个单词之间有一个空格)。
 
 
对于不带修改的链上第$k$大,我们可以对于每个点维护它到根的主席树,查询时求$tree[i]+tree[j]-tree[lca(i,j)]-tree[fa[lca(i,j)]]$即可;
带修改的话就需要用树状数组+$dfs$序,但这东西貌似和上面的主席树冲突;
所以考虑把原树部分和修改部分分开维护,先搞出$dfs$序列,每个点的意义也是它到根的主席树;
修改一个点只会影响它的子树,$i$到$j$的路径求和为$seq[i]+seq[j]-seq[lca(i,j)]-seq[fa[lca(i,j)]]$,区间加+单点求值,可以差分+树状数组套线段树;
最后查询的时候把原树和序列加在一起,二分区间就行了;
AC GET☆DAZE
 
↓代码
  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<string>
  5 #include<cstdio>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<map>
 10 #include<set>
 11 #define N 100039
 12 #define mod 998244353
 13 #define inf 0x3f3f3f3f
 14 #define ll long long
 15 #define lowbit(x) -x&x
 16 using namespace std;
 17 struct number
 18 {
 19     int n,r;
 20 }num[N<<1];
 21 struct edge
 22 {
 23     int to,next;
 24 }net[N<<1];
 25 struct question
 26 {
 27     int k,i,j;
 28 }ask[N];
 29 struct Seg_Tree
 30 {
 31     int ls,rs,w;
 32 }tree[N<<6];
 33 int n,q,rea[N<<1],rec,cnt,tot,head[N],dfn[N],siz[N],dep[N],gra[N][20];
 34 int rt_t[N],rt_s[N],L[N],R[N];
 35 map<int,int> id;
 36 void add(int u,int v)
 37 {
 38     net[++tot]=(edge){v,head[u]},head[u]=tot;
 39     net[++tot]=(edge){u,head[v]},head[v]=tot;
 40 }
 41 bool cmp_n(number i,number j) {return i.n<j.n;}
 42 bool cmp_r(number i,number j) {return i.r<j.r;}
 43 void rename()
 44 {
 45     sort(num+1,num+cnt+1,cmp_n);
 46     for(int a=1;a<=cnt;a++)
 47     {
 48         if(!id[num[a].n])
 49         {
 50             id[num[a].n]=++rec;
 51             rea[rec]=num[a].n;
 52         }
 53     }
 54     sort(num+1,num+cnt+1,cmp_r);
 55 }
 56 inline int make_new(int &k)
 57 {
 58     return k ? k : k=++cnt;
 59 }
 60 void build_tree(int now,int l,int r)
 61 {
 62     if(l==r)
 63     {
 64         return;
 65     }
 66     int mid=l+r>>1;
 67     build_tree(tree[now].ls=++cnt,l,mid);
 68     build_tree(tree[now].rs=++cnt,mid+1,r);
 69 }
 70 void update_tree(int las,int now,int l,int r,int p)
 71 {
 72     if(l==r)
 73     {
 74         tree[now].w=tree[las].w+1;
 75         return;
 76     }
 77     int mid=l+r>>1;
 78     if(p<=mid)
 79     {
 80         tree[now].rs=tree[las].rs;
 81         update_tree(tree[las].ls,tree[now].ls=++cnt,l,mid,p); 
 82     }
 83     else
 84     {
 85         tree[now].ls=tree[las].ls;
 86         update_tree(tree[las].rs,tree[now].rs=++cnt,mid+1,r,p);
 87     }
 88     tree[now].w=tree[tree[now].ls].w+tree[tree[now].rs].w;
 89 }
 90 void dfs(int pos,int pre,int de)
 91 {
 92     update_tree(rt_t[pre],rt_t[pos]=++cnt,1,rec,id[num[pos].n]);
 93     dfn[pos]=++tot,siz[pos]=1,dep[pos]=de,gra[pos][0]=pre;
 94     for(int a=1,b=2;b<=de;a++,b<<=1)
 95     {
 96         gra[pos][a]=gra[gra[pos][a-1]][a-1];
 97     }
 98     for(int a=head[pos];a;a=net[a].next)
 99     {
100         if(net[a].to!=pre)
101         {
102             dfs(net[a].to,pos,de+1);
103             siz[pos]+=siz[net[a].to];
104         }
105     }
106 }
107 int lca(int i,int j)
108 {
109     if(dep[i]>dep[j]) swap(i,j);
110     for(int a=16;~a;a--) if(dep[gra[j][a]]>=dep[i]) j=gra[j][a];
111     if(i==j) return i;
112     for(int a=16;~a;a--) if(gra[i][a]!=gra[j][a]) i=gra[i][a],j=gra[j][a];
113     return gra[i][0];
114 }
115 void update_seq(int now,int l,int r,int p,int v)
116 {
117     if(l==r)
118     {
119         tree[now].w+=v;
120         return;
121     }
122     int mid=l+r>>1;
123     if(p<=mid) update_seq(make_new(tree[now].ls),l,mid,p,v);
124     else update_seq(make_new(tree[now].rs),mid+1,r,p,v);
125     tree[now].w=tree[tree[now].ls].w+tree[tree[now].rs].w;
126 }
127 void update_bit(int p,int v)
128 {
129     int las=id[num[p].n],now=id[v];
130     for(int a=dfn[p];a<=n;a+=lowbit(a))
131     {
132         update_seq(make_new(rt_s[a]),1,rec,las,-1);
133         update_seq(make_new(rt_s[a]),1,rec,now,1);
134     }
135     for(int a=dfn[p]+siz[p];a<=n;a+=lowbit(a))
136     {
137         update_seq(make_new(rt_s[a]),1,rec,las,1);
138         update_seq(make_new(rt_s[a]),1,rec,now,-1);
139     }
140     num[p].n=v;
141 }
142 int query(int th[])
143 {
144     int res=0;
145     for(int a=1;a<=th[0];a++)
146     {
147         res+=tree[tree[th[a]].rs].w;
148     }
149     return res;
150 }
151 int query_bit(int i,int j,int k)
152 {
153     int l=1,r=rec,mid,flag=0,stp=lca(i,j);
154     L[0]=R[0]=0;
155     L[++L[0]]=rt_t[stp],L[++L[0]]=rt_t[gra[stp][0]];
156     R[++R[0]]=rt_t[i],R[++R[0]]=rt_t[j];
157     for(int a=dfn[stp];a;a-=lowbit(a)) L[++L[0]]=rt_s[a];
158     for(int a=dfn[gra[stp][0]];a;a-=lowbit(a)) L[++L[0]]=rt_s[a];
159     for(int a=dfn[i];a;a-=lowbit(a)) R[++R[0]]=rt_s[a];
160     for(int a=dfn[j];a;a-=lowbit(a)) R[++R[0]]=rt_s[a];
161     while(l<r)
162     {
163         mid=l+r>>1;
164         stp=query(R)-query(L);
165         if(stp>=k)
166         {
167             l=mid+1,flag=1;
168             for(int a=1;a<=L[0];a++) L[a]=tree[L[a]].rs;
169             for(int a=1;a<=R[0];a++) R[a]=tree[R[a]].rs;
170         }
171         else
172         {
173             r=mid,k-=stp;
174             for(int a=1;a<=L[0];a++) L[a]=tree[L[a]].ls;
175             for(int a=1;a<=R[0];a++) R[a]=tree[R[a]].ls;
176         }
177     }
178     return flag ? rea[r] : -1;
179 }
180 int main()
181 {
182     scanf("%d%d",&n,&q);
183     for(int a=1;a<=n;a++)
184     {
185         scanf("%d",&num[a].n);
186         num[a].r=++cnt;
187     }
188     for(int a=1,b,c;a<n;a++)
189     {
190         scanf("%d%d",&b,&c);
191         add(b,c);
192     }
193     for(int a=1;a<=q;a++)
194     {
195         scanf("%d%d%d",&ask[a].k,&ask[a].i,&ask[a].j);
196         if(!ask[a].k)
197         {
198             num[++cnt]=(number){ask[a].j,cnt};
199         }
200     }
201     rename(),cnt=0;
202     build_tree(rt_t[0]=++cnt,1,rec);
203     tot=0,dep[0]=-1,dfs(1,0,0);
204     for(int a=1,b;a<=q;a++)
205     {
206         if(!ask[a].k)
207         {
208             update_bit(ask[a].i,ask[a].j);
209         }
210         else
211         {
212             b=query_bit(ask[a].i,ask[a].j,ask[a].k);
213             if(~b) printf("%d\n",b);
214             else puts("invalid request!");
215         }
216     }
217     return 0;
218 }
bzoj1146

 

posted @ 2018-01-29 16:09  Sinogi  阅读(203)  评论(0编辑  收藏  举报