[ZJOI2008]树的统计

树剖板子题。

但是我太弱了。

没有看见值域是[-30000,30000],然后把mx的最小值设的-1。。。问问问

改了就A了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=30005;
int n,nxt[N<<1],to[N<<1],ecnt,head[N],siz[N],son[N],rnk[N],dfn1[N],dfn2[N],tim,
top[N],fa[N],dep[N],ans,mx,a[N];
struct Segtree{int l,r,sum,lazy,mx;}seg[N<<2];
inline void add(int bg,int ed) {nxt[++ecnt]=head[bg];to[ecnt]=ed;head[bg]=ecnt;}
#define mid (l+r>>1)
#define ls (cur<<1)
#define rs (cur<<1|1)
inline void pushup(int cur) {seg[cur].sum=seg[ls].sum+seg[rs].sum;seg[cur].mx=max(seg[ls].mx,seg[rs].mx);}
inline void pushdown(int cur) {
    if(seg[cur].lazy==-19260817) return;
    seg[ls].sum=seg[cur].lazy*(seg[ls].r-seg[ls].l+1);seg[ls].lazy=seg[cur].lazy;
    seg[ls].mx=seg[cur].lazy;
    seg[rs].sum=seg[cur].lazy*(seg[rs].r-seg[rs].l+1);seg[rs].lazy=seg[cur].lazy;
    seg[rs].mx=seg[cur].lazy;
    seg[cur].lazy=-19260817;
    return;
}
void build(int l,int r,int cur) {
    seg[cur].l=l,seg[cur].r=r;seg[cur].lazy=-19260817;
    if(l==r) {seg[cur].sum=seg[cur].mx=a[rnk[l]];seg[cur].lazy=-19260817;return;}
    build(l,mid,ls),build(mid+1,r,rs);
    pushup(cur);
}
void update(int l,int r,int cur,int c) {
    if(l>seg[cur].r||r<seg[cur].l) return;
    if(l<=seg[cur].l&&r>=seg[cur].r) {
    seg[cur].lazy=c;seg[cur].sum=(seg[cur].r-seg[cur].l+1)*c;seg[cur].mx=c;return;
    }
    pushdown(cur);
    update(l,r,ls,c);
    update(l,r,rs,c);
    pushup(cur);
}
void query(int l,int r,int cur) {
    if(l>seg[cur].r||r<seg[cur].l) return;
    if(l<=seg[cur].l&&r>=seg[cur].r) {ans+=seg[cur].sum;mx=max(mx,seg[cur].mx);return;}
    pushdown(cur);
    query(l,r,ls);
    query(l,r,rs);
    return;
}
void dfs(int x) {
    siz[x]=1;
    for(int i=head[x];i;i=nxt[i]) {
        if(to[i]!=fa[x]) {
            fa[to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]),siz[x]+=siz[to[i]];
            if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
        }
    }
}
void dfs(int x,int qtop) {
    top[x]=qtop;dfn1[x]=++tim;rnk[tim]=x;
    if(!son[x]) return;
    dfs(son[x],qtop);
    for(int i=head[x];i;i=nxt[i]) {
        if(to[i]!=son[x]&&to[i]!=fa[x]) dfs(to[i],to[i]);
    }
    dfn2[x]=tim;
}
void add_path(int x,int y,int c) {
    int f1=top[x],f2=top[y];
    while(f1!=f2) {
        if(dep[f1]<dep[f2])swap(f1,f2),swap(x,y);
        update(dfn1[f1],dfn1[x],1,c);
        x=fa[f1],f1=top[x];
    }
    if(dep[x]<dep[y]) update(dfn1[x],dfn1[y],1,c);
    else update(dfn1[y],dfn1[x],1,c);
}
void query_path(int x,int y) {
    mx=-19260817;ans=0;
    int f1=top[x],f2=top[y];
    while(f1!=f2) {
        if(dep[f1]<dep[f2])swap(f1,f2),swap(x,y);
        query(dfn1[f1],dfn1[x],1);
        x=fa[f1],f1=top[x];
    }
    if(dep[x]<=dep[y]) query(dfn1[x],dfn1[y],1);
    else query(dfn1[y],dfn1[x],1);
}
int main() {
    scanf("%d",&n);
    for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    dfs(1);
    dfs(1,1);
    build(1,n,1);
    int T;
    scanf("%d",&T);
    char opt[20];int x,y;
    while(T--) {
        scanf("%s%d%d",opt,&x,&y);
        if(opt[0]=='C') add_path(x,x,y);
        else {
            query_path(x,y);
            if(opt[1]=='M') printf("%d
",mx);
            else if(opt[1]=='S') printf("%d
",ans);
        }
    }
    return 0;
}
树的统计
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9683058.html