求大佬调动态开点线段树 /kel
查看原帖
求大佬调动态开点线段树 /kel
236929
Monaco楼主2021/9/30 11:21

Rt

蒟蒻样例最后一个过不去,34Pts,Wa7个点

#include<bits/stdc++.h>
const int N=1e6+10;
int tot,shabi,head[N]; 
struct node
{
  int v,next;
}e[N*2];
inline void add(register int u,register int v)
{
  e[++tot].v=v,e[tot].next=head[u],head[u]=tot; 
}
using namespace std;
int maxi[N*10],sum[N*10],root[N*10],ls[N*10],rs[N*10];
int f[N],dep[N],maxson[N],Size[N],top[N],id[N];
int wi[N],dat[N],cnt,n; 
void dfs1(int now,int fa)
{
  f[now]=fa; dep[now]=dep[fa]+1;
  maxson[now]=0;Size[now]=1; 
  for(int i=head[now];i;i=e[i].next)
  {
    int v=e[i].v;
    if(v!=fa)
    {
      dfs1(v,now); 
      Size[now]+=Size[v]; 
      if(Size[v]>Size[maxson[now]]) maxson[now]=v; 
    }
  }
}
void dfs2(int now,int topi)
{
  top[now]=topi; id[now]=++cnt;
  if(!maxson[now]) return; 
  
  dfs2(maxson[now],topi); 
  for(int i=head[now];i;i=e[i].next)
  {
    int v=e[i].v;
    if(v!=f[now]&&v!=maxson[now])
    {
      dfs2(v,v); 
    }
  }
}
void build(int &rt,int l,int r,int P, int K)
{
  if(!rt){rt=     ++cnt; }
  if(l==r) {sum[rt]=maxi[rt]=K; return ;}
  int mid=(l+r)>>1;
  if(P<=mid) build(ls[rt],l,mid,P,K);
  else build(rs[rt],mid+1,r,P,K);
  sum[rt]=sum[ls[rt]]+sum[rs[rt]];
  maxi[rt]=max(maxi[ls[rt]],maxi[rs[rt]]); 
}
void remove(int rt,int l,int r,int X)
{
  if(l==r) {maxi[rt]=sum[rt]=0; return ; }
  if(X<=((l+r)>>1)) remove(ls[rt],l,((l+r)>>1),X);
  else remove(rs[rt],((l+r)>>1)+1,r,X);
  maxi[rt]=max(maxi[ls[rt]],maxi[rs[rt]]);
  sum[rt]=sum[ls[rt]]+sum[rs[rt]]; 
}
int Mquery(int rt,int l,int r,int L,int R)
{
  if(L<=l&&R>=r){return maxi[rt];}
  int ans=0;
  if(L<=((l+r)>>1)) ans=max(ans,Mquery(ls[rt],l,((l+r)>>1),L,R));
  if(R>((l+r)>>1)) ans=max(ans,Mquery(rs[rt],((l+r)>>1)+1,r,L,R));
  return ans;
}
int Squery(int rt,int l,int r,int L,int R)
{
  if(L<=l&&R>=r){return sum[rt];}
  int ans=0;
  if(L<=((l+r)>>1)) ans+=Squery(ls[rt],l,((l+r)>>1),L,R);
  if(R>((l+r)>>1)) ans+=Squery(rs[rt],((l+r)>>1)+1,r,L,R);
  return ans;
}
int Xsum(int x,int y)
{
  int ans=0,zj=wi[y];
  while(top[x]!=top[y])
  {
    if(dep[top[x]]<dep[top[y]]) swap(x,y);
    ans+=Squery(root[zj],1,n,id[top[x]],id[x]); 
    x=f[top[x]]; 
  }
  if(dep[x]>dep[y]) swap(x,y); 
  ans+=Squery(root[zj],1,n,id[x],id[y]);
  return ans;
}
int Xmax(int x,int y)
{
  int ans=0,zj=wi[y];
  while(top[x]!=top[y])
  {
    if(dep[top[x]]<dep[top[y]]) swap(x,y);
    ans=max(ans,Mquery(root[zj],1,n,id[top[x]],id[x])); 
    x=f[top[x]]; 
  }
  if(dep[x]>dep[y]) swap(x,y); 
  ans=max(ans,Mquery(root[zj],1,n,id[x],id[y]));
  return ans;
}
/*void test(int rt,int l,int r)
{
  cout<<rt<<" "<<l<<" "<<r<<" "<<maxi[rt]<<endl;
  if(l==r||(!rt)) return ;
  test(ls[rt],l,(l+r)>>1);
  test(rs[rt],((l+r)>>1)+1,r); 
}*/
int main()
{
  int q;
  cin>>n>>q;
  for(int i=1;i<=n;++i)
  {
    cin>>dat[i]>>wi[i]; 
  }
  for(int i=1;i<n;++i)
  {
    int u,v;
    cin>>u>>v;
    add(u,v); add(v,u); 
  }
  dfs1(1,1); 
  dfs2(1,1); 
  //for(int i=1;i<=n;++i) cout<<" "<<top[i]<<" "<<maxson[i]<<endl;
  for(int i=1;i<=n;++i)
  {
    build(root[wi[i]],1,n,id[i],dat[i]); 
  }
  for(int i=1;i<=q;++i)
  {
    string opt; cin>>opt; 
    int x,y; cin>>x>>y; 
    if(opt[1]=='C')  //x改信y教
    // dat 是评级,w 是宗教
    {
      remove(root[wi[x]],1,n,id[x]);
      build(root[y],1,n,id[x],dat[x]);
      wi[x]=y;
    }
    else if(opt[1]=='W')
    {
      remove(root[wi[x]],1,n,id[x]);
      build(root[wi[x]],1,n,id[x],y);
      dat[x] = y;
    }
    else if(opt[1]='S') 
    {
      printf("%d\n",Xsum(x,y));
    }
    else printf("%d\n",Xmax(x,y));
  }
  return 0; 
}
2021/9/30 11:21
加载中...