萌新刚学树剖,全wa求调
查看原帖
萌新刚学树剖,全wa求调
589600
AH20楼主2022/8/7 12:50
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 1e5 + 5;
const ll inf=1e17;
ll fa[MAXN];
ll dep[MAXN];
ll siz[MAXN];
ll son[MAXN];
ll top[MAXN];
ll dfn[MAXN];
ll rnk[MAXN];
char op[10];
vector<ll>edge[MAXN];
ll cnt=0;
struct node{
   ll l,r,sum,maxx;
};
ll   n, m, A[MAXN];
node tree[MAXN<<2];
void push_up(int p){
 if(tree[p].l==tree[p].r) return;
 tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
 tree[p].maxx=max(tree[p<<1].maxx,tree[p<<1|1].maxx);
}
void build(int p = 1, int cl = 1, int cr = n)
{
    tree[p].l=cl;
    tree[p].r=cr;
    if (cl == cr) {
        tree[p].sum=A[cl];
        tree[p].maxx=A[cl];
        tree[p].l=tree[p].r=cr;
        return;
    }
    int mid = (cl + cr) >> 1;
    build(p << 1, cl, mid);
    build(p << 1 | 1, mid + 1, cr);
    push_up(p);
}
ll query(int l, int r, int p=1)
{
    ll cl=tree[p].l,cr=tree[p].r;
    if(cl>r||cr<l) return 0;
    if (cl >= l && cr <= r) return tree[p].sum;
    ll mid = (cl + cr) >> 1, ans = 0;
    if (mid >= l) ans += query(l, r, p << 1);
    if (mid < r) ans += query(l, r, p << 1 | 1);
    return ans;
}
ll qmax(int l,int r,int p=1){
   ll cl=tree[p].l,cr=tree[p].r;
   if(cl>r||cr<l) return 0;
   if (cl >= l && cr <= r) return tree[p].maxx;
   ll mid=(cl+cr)>>1;
   ll maxx=-inf;
   if(mid>=l) maxx=max(maxx,qmax(l,r,p<<1));
   if(mid<r)  maxx=max(maxx,query(l,r,p<<1|1));
   return maxx;
}
void change(ll loc,ll p,ll x){
    ll cl=tree[p].l,cr=tree[p].r;
     if(tree[p].l==loc and tree[p].r==loc){
         tree[p].sum=tree[p].maxx=x;
         return;
     }
     ll mid=(cl+cr)>>1;
     if(mid>=loc) change(loc,p<<1,x);
     else change(loc,p<<1|1,x);
     push_up(p);
}
void dfs1(ll now,ll Fa,ll depth){
     fa[now]=Fa;
     dep[now]=depth;
     siz[now]=1;
     if(edge[now].size()==1&&edge[now][0]==Fa){return;}
     for(auto i:edge[now]){
        if(i==Fa) continue;
        dfs1(i,now,depth+1);
        siz[now]+=siz[i];
        if(siz[son[now]]<siz[i]) son[now]=i;
     }
}
void dfs2(ll now,ll fa,ll step){
     if(step==0) top[now]=now;
     else top[now]=top[fa];
     dfn[++cnt]=now;
     rnk[now]=cnt;
     if(son[now]==0) return;
     dfs2(son[now],now,step+1);
     for(auto i:edge[now]){
        if(i==fa||i==son[now]||dep[i]<dep[now]) continue;
        dfs2(i,-1,0);
     }
}
ll LCA(ll x,ll y){
   while(top[x]!=top[y]){
      if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
      else y=fa[top[y]];
   }
   return dep[x]>dep[y]?y:x;
}
int main(){
    scanf("%lld",&n);
    for(int i=1;i<n;i++){
        ll a,b;
        scanf("%lld%lld",&a,&b);
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    dfs1(1,1,0);
    dfs2(1,1,0);
    for(int i=1;i<=n;i++){
        ll tmp;
        scanf("%lld",&tmp);
        A[dfn[i]]=tmp;
    }
    build();
    scanf("%lld",&m);
    while(m--){
        scanf("%s",op);
        if(!strcmp(op,"CHANGE")){
            ll u,t;
            scanf("%lld%lld",&u,&t);
            change(rnk[u],1,t);
        }
        else if(!strcmp(op,"QMAX")){
            ll u,v;
            scanf("%lld%lld",&u,&v);
            ll w=LCA(u,v);
            ll maxx=-inf;
            while(top[u]!=top[w]){
                maxx=max(maxx,qmax(rnk[top[u]],rnk[u]));
                u=fa[top[u]];
            }
            maxx=max(maxx,qmax(rnk[w],rnk[u]));
             while(top[v]!=top[w]){
                maxx=max(maxx,qmax(rnk[top[v]],rnk[v]));
                v=fa[top[v]];
            }
            maxx=max(maxx,qmax(rnk[w],rnk[v]));
            printf("%lld\n",maxx);
        }
        else{
            ll u,v;
            scanf("%lld%lld",&u,&v);
            ll w=LCA(u,v);
            ll sum=0;
              while(top[u]!=top[w]){
               sum+=query(rnk[top[u]],rnk[u]);
                u=fa[top[u]];
            }
            sum+=query(rnk[w],rnk[u]);
              while(top[v]!=top[w]){
               sum+=query(rnk[top[v]],rnk[v]);
                v=fa[top[v]];
            }
            sum+=query(rnk[w],rnk[v]);
            sum-=query(rnk[w],rnk[w]);
            printf("%lld\n",sum);
            }
        }
    return 0;
}


2022/8/7 12:50
加载中...