BZOJ3531 [Sdoi2014] Travel - tree section + dynamic open point line segment tree

Description
S has N cities, numbered from 1 to N. The cities are connected by N-1 two-way roads, so that all other cities can be reached
from one city. Each city believes in different religions, such as flying noodle religion, invisible unicorn religion, and Jedi religion are all common beliefs. For convenience, we use different positive integers to represent various religions, and the residents of country S often travel. They always took the shortest route when traveling, and to avoid trouble, they only stayed in cities of the same faith as theirs. Of course, the end of the journey is also the city of the same faith as him. The government of S country has set a different travel rating for each city, and travelers often write down the sum or maximum rating of the cities they have stayed in on the way (including the origin and destination).
In the history of country S, the following events often occurred:
"CC xc": all residents of city x converted to c religion;
"CW xw": the rating of city x was adjusted to w;
"QS xy": a traveler A traveler starts from city x, goes to city y, and records the sum of the ratings of the cities where he stays on the way;
"QM xy": A traveler starts from city x, goes to city y, and records
the rating maximum.
The numbers recorded by travelers have been lost due to age, but the beliefs and ratings of each city before the records began, as well as the event records themselves, are intact. Based on this information, restore the numbers the traveler wrote down. For convenience, we consider the intervals between events to be long enough that the ratings and beliefs of all cities remain the same on any given trip.

The first line of Input
contains the integer N, and Q represents the number of cities and the number of events in turn.
Next N lines, the i+lth line, two integers Wi, Ci, in turn, represent the
rating .
The next N-1 lines each have two integers x, y representing a two-way road.
The next Q lines, one operation per line, are formatted as described above.

Output
For each QS and QM event, output a row representing the number recorded by the traveler.

Sample Input
5 6

3 1

2 3

1 2

3 3

5 1

1 2

1 3

3 4

3 5

QS 1 5

CC 3 1

QS 1 5

CW 3 3

QS 1 5

QM 2 4

Sample Output

8
9
11
3

HINT
N,Q < =10^5 , C < =10^5

Data guarantees the same belief for all QS and QM events, origin and destination cities; at any time

At tick, the city's rating is always a positive integer no greater than 10^4, and the religion value is no greater than C.


For this question, we need to maintain the religious beliefs and ratings of each city. At the same time we also maintain the rating and value and maximum value of each node of the same religion. So we will think of the operation of adding line segment tree with tree chain division. However, the data range is as high as 10^5, and the ordinary segment tree will definitely be MLE, so we have to use the dynamic open-point segment tree. Dynamic open point line segment tree is to create a new node when it is used.
We can first look at the build operation of the dynamic open point line segment tree
void build(int &node,int l,int r,int p,int ad){
    if(!node) node=++k;
    if(l==r){
        sum[node]=maxi[node]=ad;
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid) build(lc[node],l,mid,p,ad);
    else build(rc[node],mid+1,r,p,ad);
    up(node);
}
Here for the point node, its left son is not necessarily node<<1, and its right son is not necessarily node<<1|1, because we are doing dynamic opening, so we also need to dynamically record its left and right sons.
Since the points of different religions cannot reach each other, we must establish a dynamic open-point line segment tree for each religion. We can maintain the path from u to v by tree chain division, and for each religion establish A line segment tree can guarantee that only those of the same religion are evaluated.
Other line segment tree operations are similar to ordinary line segment trees. However, since different religions need to be established, we also need to add the religion col parameter to the query operation.
#include<bits/stdc++.h>
#define MAXN 200005
#define MAXM 10000005
using namespace std;

int read(){
    char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
    while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}

int c[MAXN],w[MAXN],fa[MAXN],son[MAXN],dep[MAXN],siz[MAXN],rank[MAXN],top[MAXN];
int head[MAXN<<1],nxt[MAXN<<1],to[MAXN<<1],cnt,gran[MAXN][20],tid;
int maxi[MAXM],sum[MAXM],lc[MAXM],rc[MAXM],root[MAXN<<1];
int n,m,k;
string s;

void add(int x,int y){
    to[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;cnt++;
    to[cnt]=x;nxt[cnt]=head[y];head[y]=cnt;cnt++;
}

void dfsI(int x,int father){
    fa[x]=father;dep[x]=dep[fa[x]]+1;
    siz[x]=1;son[x]=-1;gran[x][0]=father;
    for(int i=1;(1<<i)<=dep[x];i++) gran[x][i]=gran[gran[x][i-1]][i-1];
    for(int i=head[x];i!=-1;i=nxt[i]){
        int go=to[i];
        if(go==father) continue;
        dfsI(go,x);
        siz[x]+=siz[go];
        if(son[x]==-1||siz[go]>siz[son[x]]) son[x]=go;
    }
}

void dfsII(int x,int t){
    top[x]=t;rank[x]=++tid;
    if(son[x]==-1) return;
    dfsII(son[x],t);
    for(int i=head[x];i!=-1;i=nxt[i]){
        int go=to[i];
        if(go==fa[x]||go==son[x]) continue;
        dfsII(go,go);
    }
}

int lca(int x,int y){
    if(dep[x]>dep[y]) swap(x,y);
    for(int i=18;i>=0;i--)
       if(dep[x]<=dep[gran[y][i]]) y=gran[y][i];
    for(int i=18;i>=0;i--){
        if(gran[x][i]!=gran[y][i]){
            x=gran[x][i];y=gran[y][i];
        }
    }
    if(x==y) return x;
    else return gran[x][0];
}

void up(int node){
    sum[node]=sum[lc[node]]+sum[rc[node]];
    maxi[node]=max(maxi[lc[node]],maxi[rc[node]]);
}

void build(int &node,int l,int r,int p,int ad){
    if(!node) node=++k;
    if(l==r){
        sum[node]=maxi[node]=ad;
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid) build(lc[node],l,mid,p,ad);
    else build(rc[node],mid+1,r,p,ad);
    up(node);
}

int querySUM(int node,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        return sum[node];
    }
    int mid=(l+r)>>1,ans=0;
    if(L<=mid) ans+=querySUM(lc[node],l,mid,L,R);
    if(R>mid) ans+=querySUM(rc[node],mid+1,r,L,R);
    return ans;
}

int queryMAX(int node,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        return maxi[node];
    }
    int mid=(l+r)>>1,ans=0;
    if(L<=mid) ans=max(ans,queryMAX(lc[node],l,mid,L,R));
    if(R>mid) ans=max(ans,queryMAX(rc[node],mid+1,r,L,R));
    return ans;
}

int queryLinkSUM(int u,int v,int col){
    int ans=0;
    if(dep[top[u]]>dep[top[v]]) swap(u,v);
    while(top[u]!=top[v]){
        ans+=querySUM(root[col],1,n,rank[top[v]],rank[v]);
        v=fa[top[v]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    ans+=querySUM(root[col],1,n,rank[u],rank[v]);
    return ans;
}

int queryLinkMAX(int u,int v,int col){
    int ans=0;
    if(dep[top[u]]>dep[top[v]]) swap(u,v);
    while(top[u]!=top[v]){
        ans=max(ans,queryMAX(root[col],1,n,rank[top[v]],rank[v]));
        v=fa[top[v]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    ans=max(ans,queryMAX(root[col],1,n,rank[u],rank[v]));
    return ans;
}

int main()
{
    n=read();m=read();
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++){
        w[i]=read();c[i]=read();
    }
    for(int i=1;i<=n-1;i++){
        int x=read(),y=read();
        add(x,y);
    }
    dfsI(1,0);
    dfsII(1,1);
    for(int i=1;i<=n;i++) build(root[c[i]],1,n,rank[i],w[i]);
    for(int i=1;i<=m;i++){
        cin>>s;
        int x=read(),y=read();
        if(s=="CC"){
            build(root[c[x]],1,n,rank[x],0);
            c[x]=y;
            build(root[y],1,n,rank[x],w[x]);
        }
        if(s=="CW"){
            w[x]=y;
            build(root[c[x]],1,n,rank[x],y);
        }
        if(s=="QS"){
            int LCA=lca(x,y);
            int res=queryLinkSUM(x,LCA,c[x])+queryLinkSUM(y,LCA,c[y]);
            if(c[x]==c[LCA]) res-=w[LCA];
            printf("%d\n",res);
        }
        if(s=="QM"){
            int LCA=lca(x,y);
            printf("%d\n",max(queryLinkMAX(x,LCA,c[x]),queryLinkMAX(y,LCA,c[y])));
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325565913&siteId=291194637