bzoj1146 [CTSC2008]网络管理Network (树上带修改主席树)
1146: [CTSC2008]网络管理Network
Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 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 }
散りぬべき 時知りてこそ 世の中の 花も花なれ 人も人なれ