【bzoj1146】[CTSC2008]网络管理Network
题目描述:
M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络。该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信。 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略。但是由于路由器老化,在这些路由器上进行数据交换会带来很大的延迟。而两个路由器之间的通信延迟时间则与这两个路由器通信路径上所有路由器中最大的交换延迟时间有关。作为M公司网络部门的一名实习员工,现在要求你编写一个简单的程序来监视公司的网络状况。该程序能够随时更新网络状况的变化信息(路由器数据交换延迟时间的变化),并且根据询问给出两个路由器通信路径上延迟第k大的路由器的延迟时间。【任务】 你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们可能是: 1. 由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。 2. 查询某两个路由器a和b之间的路径上延迟第k大的路由器的延迟时间。
输入:
第一行为两个整数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大的路由器的延迟时间。注意a可以等于b,此时路径上只有一个路由器。
输出:
对于每一个第二种询问(k>0),输出一行。包含一个整数为相应的延迟时间。如果路径上的路由器不足k个,则输出信息“invalid request!”(全部小写不包含引号,两个单词之间有一个空格)。
样例输入:
5 5
5 1 2 3 4
3 1
2 1
4 3
5 3
2 4 5
0 1 2
2 2 3
2 1 4
3 3 5
样例输出:
3
2
2
invalid request!
题解:
带修改的求树上路径点权第K大。我写这道题的时候傻逼了,第K大求成第K小(居然样例还过了),没离散化被卡内存,然后二分了一下数组规模才过=。=
(这种题如果叫我考场上写肯定写不出来)
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #ifdef WIN32 #define LL "%I64d" #else #define LL "%lld" #endif #ifdef CT #define debug(...) printf(__VA_ARGS__) #define setfile() #else #define debug(...) #define filename "" #define setfile() freopen(filename".in","r",stdin);freopen(filename".out","w",stdout); #endif #define R register #define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++) #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b)) #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0) #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0) char B[1<<15],*S=B,*T=B; inline int FastIn() { R char ch;R int cnt=0;R bool minus=0; while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ; ch == '-' ?minus=1:cnt=ch-'0'; while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0'; return minus?-cnt:cnt; } #define maxn 100000 #define maxm 200000 #define maxt 13250000 const int oo = 1e8; int val[maxn], last[maxn], next[maxm], to[maxm], ecnt, pos[maxn], ncnt, spos[maxn], npos[maxn]; int ln[maxn], rn[maxn], lcan[maxn], flcan[maxn], lcnt, rcnt, lcacnt, flcacnt; int fa[maxn], depth[maxn], size[maxn], son[maxn], top[maxn]; int root[maxn], tot, ls[maxt], rs[maxt], sum[maxt]; bool vis[maxn]; #define lowbit(_x) ((_x) & -(_x)) #define add_edge(_a, _b) (to[++ecnt] = (_b), next[ecnt] = last[_a], last[_a] = ecnt) void dfs1(R int x) { size[x] = 1; depth[x] = depth[fa[x]] + 1; vis[x] = 1; pos[++ncnt] = x; npos[x] = ncnt; for (R int i = last[x]; i; i = next[i]) { R int t = to[i]; if (!vis[t]) { fa[t] = x; dfs1(t); size[x] += size[t]; size[son[x]] < size[t] ? son[x] = t : 0; } } spos[x] = ncnt; } void dfs2(R int x) { vis[x] = 0;son[fa[x]] == x ? top[x] = top[fa[x]] : top[x] = x; for (R int i = last[x]; i; i = next[i]) if (vis[to[i]]) dfs2(to[i]); } inline int getlca(R int a, R int b) { while (top[a]!=top[b]) { depth[top[a]] < depth[top[b]] ? b = fa[top[b]] : a = fa[top[a]] ; } return depth[a] < depth [b] ? a : b ; } int Insert (R int nw, R int l, R int r, R int x, R int c) { if(!nw) nw = ++tot; R int mid = (l + r) >> 1; sum[nw] += c; if (l == r) return nw; if (x > mid) { rs[nw] = Insert(rs[nw], mid + 1, r, x, c); } else { ls[nw] = Insert(ls[nw], l, mid, x, c); } return nw; } inline int Query(R int k) { R int l = 0, r = oo; while (l < r) { R int mid = l + r >> 1, count = 0; for (R int i = 1; i <= lcnt; ++i) count += sum[rs[ln[i]]]; for (R int i = 1; i <= rcnt; ++i) count += sum[rs[rn[i]]]; for (R int i = 1; i <= lcacnt; ++i) count -= sum[rs[lcan[i]]]; for (R int i = 1; i <= flcacnt; ++i) count -= sum[rs[flcan[i]]]; if (count >= k) { for (R int i = 1; i <= lcnt; ++i) ln[i] = rs[ln[i]]; for (R int i = 1; i <= rcnt; ++i) rn[i] = rs[rn[i]]; for (R int i = 1; i <= lcacnt; ++i) lcan[i] = rs[lcan[i]]; for (R int i = 1; i <= flcacnt; ++i) flcan[i] = rs[flcan[i]]; l = mid + 1; } else { for (R int i = 1; i <= lcnt; ++i) ln[i] = ls[ln[i]]; for (R int i = 1; i <= rcnt; ++i) rn[i] = ls[rn[i]]; for (R int i = 1; i <= lcacnt; ++i) lcan[i] = ls[lcan[i]]; for (R int i = 1; i <= flcacnt; ++i) flcan[i] = ls[flcan[i]]; r = mid ; k -= count; } } return l; } int main() { //setfile(); R int n = FastIn(), q = FastIn(); for (R int i = 1; i <= n; ++i) val[i] = FastIn(); for (R int i = 1; i < n; ++i) { R int a = FastIn(), b = FastIn(); add_edge(a, b);add_edge(b, a); } dfs1(1); dfs2(1); for (R int i = 1; i <= n; ++i) { R int x = pos[i]; for (R int j = i; j <= n; j += lowbit(j)) root[j] = Insert(root[j], 0, oo, val[x], 1) ; for (R int j = spos[x] + 1; j <= n; j += lowbit(j)) root[j] = Insert(root[j], 0, oo, val[x], -1) ; } for (; q; --q ) { R int k = FastIn(), a = FastIn(), b = FastIn() ; if (k) { R int lca = getlca(a, b), flca = fa[lca], s = 0; lcnt = rcnt = lcacnt = flcacnt = 0; s = depth[a] + depth[b] - depth[flca] - depth[lca]; if (s < k) puts("invalid request!"); else { for (R int i = npos[a]; i; i -= lowbit(i)) ln[++lcnt] = root[i]; for (R int i = npos[b]; i; i -= lowbit(i)) rn[++rcnt] = root[i]; for (R int i = npos[lca]; i; i -= lowbit(i)) lcan[++lcacnt] = root[i]; for (R int i = npos[flca]; i; i -= lowbit(i)) flcan[++flcacnt] = root[i]; printf("%d\n",Query(k) ); } } else { R int x = npos[a], sx = spos[a]; for (R int i = x; i <= n; i += lowbit(i)) root[i] = Insert(root[i], 0, oo, val[a], -1 ); for (R int i = sx + 1; i <= n; i += lowbit(i)) root[i] = Insert(root[i], 0, oo, val[a], 1 ); val[a] = b; for (R int i = x; i <= n; i += lowbit(i)) root[i] = Insert(root[i], 0, oo, b, 1); for (R int i = sx + 1; i <= n; i += lowbit(i)) root[i] = Insert(root[i], 0, oo, b, -1); } } return 0; }