luogu3313 [SDOI2014]旅行

Posted poorpool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu3313 [SDOI2014]旅行相关的知识,希望对你有一定的参考价值。

对每一个宗教建一棵线段树,然后树剖搞搞

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, w[100005], c[100005], uu, vv, hea[100005], cnt, dep[100005];
int fa[100005], top[100005], idx[100005], qaq, siz[100005], son[100005];
int rot[100005], orz, zdz[5000005], sum[5000005], lson[5000005];
int rson[5000005];
char ss[15];
struct Edge{
    int too, nxt, val;
}edge[200005];
void add_edge(int fro, int too){
    edge[++cnt].nxt = hea[fro];
    edge[cnt].too = too;
    hea[fro] = cnt;
}
void dfs1(int x, int f){
    fa[x] = f;
    siz[x] = 1;
    dep[x] = dep[f] + 1;
    int maxSon=-1;
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t!=f){
            dfs1(t, x);
            siz[x] += siz[t];
            if(maxSon<siz[t])   maxSon = siz[t], son[x] = t;
        }
    }
}
void dfs2(int x, int topf){
    top[x] = topf;
    idx[x] = ++qaq;
    if(!son[x]) return ;
    dfs2(son[x], topf);
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t!=fa[x] && t!=son[x])
            dfs2(t, t);
    }
}
void pushUp(int o){
    sum[o] = sum[lson[o]] + sum[rson[o]];
    zdz[o] = max(zdz[lson[o]], zdz[rson[o]]);
}
void insert(int &o, int l, int r, int x, int w){
    if(!o)  o = ++orz;
    if(l==r)    sum[o] = zdz[o] = w;
    else{
        int mid=(l+r)>>1;
        if(x<=mid)  insert(lson[o], l, mid, x, w);
        if(mid<x)   insert(rson[o], mid+1, r, x, w);
        pushUp(o);
    }
}
void clr(int &o){
    lson[o] = rson[o] = sum[o] = zdz[o] = 0;
    o = 0;
}
void shanchu(int &o, int l, int r, int x){
    if(l==r)    clr(o);
    else{
        int mid=(l+r)>>1;
        if(x<=mid)  shanchu(lson[o], l, mid, x);
        if(mid<x)   shanchu(rson[o], mid+1, r, x);
        pushUp(o);
        if(lson[o]+rson[o]==0)  clr(o);
    }
}
int querySGTSum(int o, int l, int r, int x, int y){
    if(!o)  return 0;
    if(l>=x && r<=y)    return sum[o];
    else{
        int mid=(l+r)>>1;
        int ans=0;
        if(x<=mid)  ans += querySGTSum(lson[o], l, mid, x, y);
        if(mid<y)   ans += querySGTSum(rson[o], mid+1, r, x, y);
        return ans;
    }
}
int querySGTMax(int o, int l, int r, int x, int y){
    if(!o)  return 0;
    if(l>=x && r<=y)    return zdz[o];
    else{
        int mid=(l+r)>>1;
        int ans=0;
        if(x<=mid)  ans = max(ans, querySGTMax(lson[o], l, mid, x, y));
        if(mid<y)   ans = max(ans, querySGTMax(rson[o], mid+1, r, x, y));
        return ans;
    }
}
int querySum(int uu, int vv){
    int bel=c[uu], ans=0;
    while(top[uu]!=top[vv]){
        if(dep[top[uu]]<dep[top[vv]])   swap(uu, vv);
        ans += querySGTSum(rot[bel], 1, n, idx[top[uu]], idx[uu]);
        uu = fa[top[uu]];
    }
    if(dep[uu]>dep[vv]) swap(uu, vv);
    ans += querySGTSum(rot[bel], 1, n, idx[uu], idx[vv]);
    return ans;
}
int queryMax(int uu, int vv){
    int bel=c[uu], ans=0;
    while(top[uu]!=top[vv]){
        if(dep[top[uu]]<dep[top[vv]])   swap(uu, vv);
        ans =max(ans, querySGTMax(rot[bel], 1, n, idx[top[uu]], idx[uu]));
        uu = fa[top[uu]];
    }
    if(dep[uu]>dep[vv]) swap(uu, vv);
    ans = max(ans, querySGTMax(rot[bel], 1, n, idx[uu], idx[vv]));
    return ans;
}
int main(){
    cin>>n>>m;
    for(int i=1; i<=n; i++) scanf("%d %d", &w[i], &c[i]);
    for(int i=1; i<n; i++){
        scanf("%d %d", &uu, &vv);
        add_edge(uu, vv);
        add_edge(vv, uu);
    }
    dep[1] = 1; 
    dfs1(1, 0);
    dfs2(1, 1);
    for(int i=1; i<=n; i++)
        insert(rot[c[i]], 1, n, idx[i], w[i]);
    while(m--){
        scanf("%s %d %d", ss, &uu, &vv);
        if(ss[0]==‘C‘ && ss[1]==‘C‘){
            shanchu(rot[c[uu]], 1, n, idx[uu]);
            c[uu] = vv;
            insert(rot[c[uu]], 1, n, idx[uu], w[uu]);
        }
        if(ss[0]==‘C‘ && ss[1]==‘W‘){
            w[uu] = vv;
            insert(rot[c[uu]], 1, n, idx[uu], w[uu]);
        }
        if(ss[0]==‘Q‘ && ss[1]==‘S‘)
            printf("%d\n", querySum(uu, vv));
        if(ss[0]==‘Q‘ && ss[1]==‘M‘)
            printf("%d\n", queryMax(uu, vv));
    }
    return 0;
}

以上是关于luogu3313 [SDOI2014]旅行的主要内容,如果未能解决你的问题,请参考以下文章

luogu_P3313 [SDOI2014]旅行

[SDOI2014]旅行

luoguP3313 [SDOI2014]旅行

题解SDOI2014旅行

[题解]luogu_P3313_旅行(树剖

[SDOI2014]旅行