3730: 震波

来源:互联网 发布:zbrush for mac 编辑:程序博客网 时间:2024/05/17 07:24

3730: 震波

Time Limit: 15 Sec  Memory Limit: 256 MB
Submit: 635  Solved: 151
[Submit][Status][Discuss]

Description

在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]。
不幸的是,这片土地常常发生地震,并且随着时代的发展,城市的价值也往往会发生变动。
接下来你需要在线处理M次操作:
0 x k 表示发生了一次地震,震中城市为x,影响范围为k,所有与x距离不超过k的城市都将受到影响,该次地震造成的经济损失为所有受影响城市的价值和。
1 x y 表示第x个城市的价值变成了y。
为了体现程序的在线性,操作中的x、y、k都需要异或你程序上一次的输出来解密,如果之前没有输出,则默认上一次的输出为0。

Input

第一行包含两个正整数N和M。
第二行包含N个正整数,第i个数表示value[i]。
接下来N-1行,每行包含两个正整数u、v,表示u和v之间有一条无向边。
接下来M行,每行包含三个数,表示M次操作。

Output

包含若干行,对于每个询问输出一行一个正整数表示答案。

Sample Input

8 1
1 10 100 1000 10000 100000 1000000 10000000
1 2
1 3
2 4
2 5
3 6
3 7
3 8
0 3 1

Sample Output

11100101

HINT

1<=N,M<=100000

1<=u,v,x<=N

1<=value[i],y<=10000

0<=k<=N-1

Source

[Submit][Status][Discuss]

考虑实施维护任意一条路径的信息,对于原树,构建成点分树
就是点分治的时候每次选出的重心,用重心链构成树,这样树高是O(logn)
剩下维护信息就很直白了,每个点用一些动态长度的树状数组维护里面的信息
不过代码细节挺多的= =挑了好久
#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<algorithm>using namespace std; const int maxn = 1E5 + 10;const int INF = ~0U>>1; int n,m,LastAns,rt,Max,O,cnt,val[maxn],siz[maxn],L[maxn],MaxD[maxn];bool Huge[maxn]; vector <int> v[maxn],G[maxn],h[maxn],Num[maxn],Dep[maxn],A[maxn],B[maxn]; int min(const int &x,const int &y) {return x < y ? x : y;} void Dfs1(int x,int tot,int fa){    int ma = 0; siz[x] = 1;    for (int i = 0; i < v[x].size(); i++)    {        int to = v[x][i];        if (to == fa || Huge[to]) continue;        Dfs1(to,tot,x); siz[x] += siz[to]; ma = max(ma,siz[to]);    }    ma = max(ma,tot - siz[x]);    if (ma < Max) Max = ma,O = x;} void Dfs2(int x,int fa){    for (int i = 0; i < v[x].size(); i++)    {        int to = v[x][i]; if (to == fa || Huge[to]) continue;        L[to] = MaxD[to] = L[x] + 1; Dfs2(to,x); MaxD[x] = max(MaxD[x],MaxD[to]);    }} void Dfs3(int x,int o,int y,int num,int t1,int t2,int fa){    siz[x] = 1; Num[x].push_back(num); Dep[x].push_back(L[x]);    for (int i = L[x]; i <= t1; i += i&-i) A[o][i] += val[x];    for (int i = L[x]; i <= t2; i += i&-i) B[y][i] += val[x];    for (int i = 0; i < v[x].size(); i++)    {        int to = v[x][i];        if (Huge[to] || to == fa) continue;        Dfs3(to,o,y,num,t1,t2,x); siz[x] += siz[to];    }} int Work(int x,int tot){    Max = INF; Dfs1(x,tot,0); int o = O,Now = 0;    Huge[o] = 1; L[o] = MaxD[o] = 0; Dfs2(o,0);    for (int i = 0; i <= MaxD[o]; i++) A[o].push_back(0);    for (int i = 0; i < v[o].size(); i++)    {        int to = v[o][i]; if (Huge[to]) continue; ++cnt;        for (int j = 0; j <= MaxD[to]; j++) B[cnt].push_back(0);        Dfs3(to,o,cnt,Now++,MaxD[o],MaxD[to],0); h[o].push_back(cnt);    }    for (int i = 0; i < v[o].size(); i++)    {        int to = v[o][i];        if (Huge[to]) continue;        int Nex = Work(to,siz[to]);        G[o].push_back(Nex);    }    return o;} int Query(int x,int y,int k,int now){    int ret = 0;    if (x == y)    {        for (int i = min(k,A[x].size() - 1); i > 0; i -= i&-i) ret += A[x][i];        return ret + val[x];    }    else    {        int Nex = h[x][Num[y][now]],st = k - Dep[y][now];        for (int i = min(st,A[x].size() - 1); i > 0; i -= i&-i) ret += A[x][i];        for (int i = min(st,B[Nex].size() - 1); i > 0; i -= i&-i) ret -= B[Nex][i];        Nex = G[x][Num[y][now]]; if (Dep[y][now] <= k) ret += val[x];        return ret + Query(Nex,y,k,now + 1);    }} void Modify(int x,int y,int va,int now){    if (x == y) {val[x] = va; return;}    int Nex = h[x][Num[y][now]],dep = Dep[y][now];    for (int j = dep; j < A[x].size(); j += j&-j) A[x][j] += (va - val[y]);    for (int j = dep; j < B[Nex].size(); j += j&-j) B[Nex][j] += (va - val[y]);    Nex = G[x][Num[y][now]];    Modify(Nex,y,va,now + 1);} int getint(){    char ch = getchar(); int ret = 0;    while (ch < '0' || '9' < ch) ch = getchar();    while ('0' <= ch && ch <= '9')        ret = ret*10 + ch - '0',ch = getchar();    return ret;} int main(){    #ifdef DMC        freopen("DMC.txt","r",stdin);    #endif         n = getint(); m = getint();    for (int i = 1; i <= n; i++) val[i] = getint();    for (int i = 1; i < n; i++)    {        int x = getint(),y = getint();        v[x].push_back(y); v[y].push_back(x);    }    rt = Work(1,n);         for (int I = 1; I <= m; I++)    {        int typ = getint(),x = getint(),y = getint();        x ^= LastAns; y ^= LastAns; if (typ) Modify(rt,x,y,0);        else printf("%d\n",LastAns = Query(rt,x,y,0));    }    return 0;}

0 0
原创粉丝点击