社区讨论

学oi一年了 男孩子 以及这个树剖莫名其妙炸了

P2590[ZJOI2008] 树的统计参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mi7cnui5
此快照首次捕获于
2025/11/20 19:30
4 个月前
此快照最后确认于
2025/11/20 19:30
4 个月前
查看原帖
CPP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define il inline
#define f(i,a,n) for(register int i=a;i<=n;++i)
#define mid ((l+r)>>1)
#define v e[i].to
#define lson fl(p),l,mid
#define rson fr(p),mid+1,r

using namespace std;
il int fl(int x) {return x<<1;}
il int fr(int x) {return x<<1|1;}
il int lb(int x) {return x&(-x);}
il int re()
 {
    int res=0,b=1;char c=getchar();
    while(('0'>c||c>'9')&&c!='-') c=getchar();
    if(c=='-') b=-b,c=getchar();
    while(c>='0'&&c<='9') res=(res<<1)+(res<<3)+c-'0',c=getchar();
    return res*b;
 }

int siz[30500],son[30500],dep[30500],fa[30500];
int id[30500],top[30500],tot;
int zkw,tree[60500],mx[60500];
int head[30500],cnt;
int n,m;
char use[60];
struct edge{int fa,to;}e[60500];

void addedge(int a,int b)
 {
  e[++cnt].fa=head[a];
  e[cnt].to=b;
  head[a]=cnt;
 }

void dfs(int u,int f)
 {
   dep[u]=dep[f]+1;
   fa[u]=f;
   siz[u]=1;
   int maxson=-1;
   for(int i=head[u];i;i=e[i].fa)
    {
      if(v==f) continue;
      dfs(v,u);
      siz[u]+=siz[v];
      if(maxson<siz[v]) maxson=siz[v],son[u]=v;
    }
 }

void dfs2(int u,int root)
 {
   top[u]=root;
   id[u]=++tot;
   if(!son[u]) return;
   dfs2(son[u],root);
   for(int i=head[u];i;i=e[i].fa)
    {
      if(v==fa[u]||v==son[u]) continue;
      dfs2(v,v);
    }
 }

void change(int p,int n)
 {
    int a=p+zkw;
    tree[a]=n,mx[a]=n;
    for(a>>=1;a;a>>=1)
    tree[a]=tree[fl(a)]+tree[fr(a)];
    mx[a]=max(mx[fl(a)],mx[fr(a)]);
 }

int askmx(int l,int r)
 {
   int res=-19260817;
   for(int s=l+zkw-1,t=r+zkw+1;s^t^1;s>>=1,t>>=1)
    {
      if(~s&1) res=max(res,mx[s^1]);
      if(t&1) res=max(res,mx[t^1]);
    }
   return res; 
 }

int asknum(int l,int r)
 {
   int res=0;
   for(int s=l+zkw-1,t=r+zkw+1;s^t^1;s>>=1,t>>=1)
    {
      if(~s&1) res+=tree[s^1];
      if(t&1) res+=tree[t^1];
    }
   return res;
 }

void setup()
 {
   n=re();
   for(zkw=1;zkw<=n+1;zkw<<=1);
   f(i,1,n-1)
    {
      int a=re(),b=re();
      addedge(a,b);
      addedge(b,a);
    }
   dfs(1,0);
   dfs2(1,1);
   f(i,zkw+n+1,zkw+zkw-1) mx[i]=-192608;
   f(i,1,n)
    {
      int c=re();
      tree[id[i]+zkw]=c;
      mx[id[i]+zkw]=c;
    }
   for(int i=zkw-1;i>=1;i--)
    tree[i]=tree[fl(i)]+tree[fr(i)],
    mx[i]=max(mx[fl(i)],mx[fr(i)]);
   
   m=re();    
 }

int sum(int x,int y)
 {
   int ans=0;
   while(top[x]!=top[y])
    {
      if(dep[top[x]]<dep[top[y]]) swap(x,y);
      ans+=asknum(id[top[x]],id[x]);
      x=fa[top[x]];
    }
   if(dep[x]>dep[y]) swap(x,y);
   ans+=asknum(id[x],id[y]);
   return ans; 
 }

int maxnum(int x,int y)
 {
  int ans=-192608;
  while(top[x]!=top[y])
   {
     if(dep[top[x]]<dep[top[y]]) swap(x,y);
     ans=max(ans,askmx(id[top[x]],id[x]));
     x=fa[top[x]];
   }
   if(dep[x]>dep[y]) swap(x,y);
   ans=max(ans,askmx(id[x],id[y]));
   return ans; 
 }

int main()
 {
   setup();
   f(j,1,m)
    {
       int x,y;
       scanf("%s%d%d",use,&x,&y);
       if(use[0]=='C') change(id[x],y);
       else
        {
          if(use[1]=='M')  printf("%d\n",maxnum(x,y));
          else printf("%d\n",sum(x,y)); 
        } 
    }
    return 0;
 }

大佬求教啊,不想noip前这个树剖炸掉啊(QAQ)

回复

3 条回复,欢迎继续交流。

正在加载回复...