[문제 풀이] luoguP3313_여행

14594 단어
나무 절개, 사실은 신앙 은 바로 색깔 입 니 다. 이런 색채 문제 에 대해 우 리 는 모든 색채 의 위 치 를 유지 하고 모든 색채 에 대해 데이터 구조 로 유지 하 며 합병 과 같은 조작 을 지원 할 수 있 습 니 다. 여 기 는 모든 색채 에 대해 동적 으로 가중치 선분 수 를 유지 할 수 있 습 니 다. 선분 수 는 이 색채 의 특정한 가중치 를 유지 할 수 있 습 니 다. 없 으 면 이 색채 에 없습니다.수정 은 그냥 지우 고 수정 같은 거 하면 돼 요.
#include
#define mid ((l+r)>>1)
using namespace std;
const int maxn=100009;
int n,m,w[maxn],c[maxn],tot;
struct node{
    int v,nxt;
}e[maxn<<1];
int head[maxn],cnt;
inline void add(int u,int v){
    e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
}
int fa[maxn],dep[maxn],siz[maxn],son[maxn],dfn[maxn],id[maxn],top[maxn];
void dfs1(int x,int f){
    siz[x]=1;dep[x]=dep[f]+1;fa[x]=f;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].v;if(y==f)continue;
        dfs1(y,x);
        siz[x]+=siz[y];
        if(siz[y]>siz[son[x]])son[x]=y;
    }
}
void dfs2(int x,int tp){
    top[x]=tp;
    dfn[x]=++tot;
    id[tot]=x;
    if(!son[x])return;
    dfs2(son[x],tp);
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].v;if(y==fa[x]||y==son[x])continue;
        dfs2(y,y);
    }
}
int root[maxn],ls[maxn*30],rs[maxn*30];
struct ttt{
    int mx,sum;
}t[maxn*30];
inline void upd(int x){
    t[x].sum=t[ls[x]].sum+t[rs[x]].sum;
    t[x].mx=max(t[ls[x]].mx,t[rs[x]].mx);
}
inline void change(int &x,int l,int r,int pos,int val){//dfs  pos,  val 
    if(!x)x=++tot;
    t[x].mx=max(t[x].mx,val),t[x].sum+=val;
    if(l==r)return;
    if(pos<=mid)change(ls[x],l,mid,pos,val);
    else change(rs[x],mid+1,r,pos,val);
}
inline void del(int &x,int l,int r,int pos){
    if(l==r){
        t[x].sum=t[x].mx=0;return;
    }
    if(pos<=mid)del(ls[x],l,mid,pos);
    else del(rs[x],mid+1,r,pos);
    upd(x);
}
inline int qSum(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R)return t[x].sum;
    int ans=0;
    if(L<=mid)ans+=qSum(ls[x],l,mid,L,R);
    if(R>mid)ans+=qSum(rs[x],mid+1,r,L,R);
    return ans;
}
inline int qMx(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R)return t[x].mx;
    int ans=0;
    if(L<=mid)ans=max(ans,qMx(ls[x],l,mid,L,R));
    if(R>mid)ans=max(ans,qMx(rs[x],mid+1,r,L,R));
    return ans;
}
inline int qMxRoute(int x,int y,int val){
    int ans=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        ans=max(ans,qMx(root[val],1,n,dfn[top[x]],dfn[x]));
        x=fa[top[x]];
    }
    if(dep[x]<dep[y])swap(x,y);
    ans=max(ans,qMx(root[val],1,n,dfn[y],dfn[x]));
    return ans;
}
inline int qSumRoute(int x,int y,int val){
    int ans=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        ans+=qSum(root[val],1,n,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y])swap(x,y);
    ans+=qSum(root[val],1,n,dfn[y],dfn[x]);
    return ans;
}
int main(){
//    freopen("test.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&c[i]);
    for(int i=1,u,v;i){
        scanf("%d%d",&u,&v);add(u,v);add(v,u);
    }
    dfs1(1,0);dfs2(1,1);
    for(int i=1;i<=n;i++)change(root[c[i]],1,n,dfn[i],w[i]);
    char op[10];
    for(int i=1,x,y;i<=m;i++){
        scanf("%s",op);
        scanf("%d%d",&x,&y);
        if(op[1]=='C'){
            del(root[c[x]],1,n,dfn[x]);
            change(root[y],1,n,dfn[x],w[x]);
            c[x]=y;
        }
        else if(op[1]=='W'){
            del(root[c[x]],1,n,dfn[x]);
            change(root[c[x]],1,n,dfn[x],y);
            w[x]=y;
        }
        else if(op[1]=='S')printf("%d
",qSumRoute(x,y,c[x])); else printf("%d
",qMxRoute(x,y,c[x])); } }

좋은 웹페이지 즐겨찾기