树剖板子70Pts,TLE三个点,求助
查看原帖
树剖板子70Pts,TLE三个点,求助
236929
Monaco楼主2021/9/29 16:49

Rt

代码:

#include<bits/stdc++.h>
#define int long long
#define mod(fst) ((fst)<p?(fst):((fst)-p))
#define mid ((l+r)>>1)
#define lson (rt)<<1,l,mid
#define rson (rt)<<1|1,mid+1,r
using namespace std;
const int N=1e6+10; 
struct node
{
  int v,next;
}e[N*2];
int n,p,dep[N],id[N],lazy[N<<2],sum[N<<2],Size[N],dat[N],tot,head[N],f[N],son[N],top[N],cnt,dati[N];
void add(int u,int v)
{
  e[++tot].v=v,e[tot].next=head[u],head[u]=tot; 
}
void dfs(int now,int fa)
{
  f[now]=fa;dep[now]=dep[fa]+1; 
  son[now]=0; Size[now]=1; 
  for(int i=head[now];i;i=e[i].next)
  {
    int v=e[i].v;
    if(v!=fa) 
    {
      dfs(v,now);
      Size[now]+=Size[v];
      if(Size[v]>Size[son[now]]) son[now]=v; 
    }
  }
}
void dfs2(int now,int topi)
{
  top[now]=topi;
  id[now]=++cnt; //dfn 序 
  dati[cnt]=dat[now]; 
  if(!son[now]) return ;
  dfs2(son[now],topi);
  for(int i=head[now];i;i=e[i].next)
  {

    int v=e[i].v;
    if(v!=f[now]&&v!=son[now])
    {
      dfs2(v,v); 
    }
  }
}
void build(int rt,int l,int r)
{
  if(l==r) 
  {
    sum[rt]=dati[l];
    return ;
  }
  build(lson);
  build(rson);
  sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 
}
void pushdown(int rt,int l,int r)
{
  lazy[rt<<1]=mod(lazy[rt<<1]+lazy[rt]);
  lazy[rt<<1|1]=mod(lazy[rt<<1|1]+lazy[rt]);
  sum[rt<<1]=mod(sum[rt<<1]+(mid-l+1)*lazy[rt]%p);
  sum[rt<<1|1]=mod(sum[rt<<1|1]+(r-mid)*lazy[rt]%p);
  lazy[rt]=0; 
}
void change(int rt,int l,int r,int L,int R,int Z)
{
  if(L<=l&&R>=r)
  {
    lazy[rt]=mod(lazy[rt]+Z);
    sum[rt]=mod(sum[rt]+(r-l+1)*Z%p); 
    return ; 
  }
  if(lazy[rt])pushdown(rt,l,r); 
  if(L<=mid) change(lson,L,R,Z);
  if(R>mid) change(rson,L,R,Z);
  sum[rt]=mod(sum[rt<<1]+sum[rt<<1|1]); 
}
int query(int rt,int l,int r,int L,int R)
{
  if(L<=l&&R>=r) return mod(sum[rt]);
  if(lazy[rt])pushdown(rt,l,r);
  int ans=0; 
  if(L<=mid) ans=mod(ans+query(lson,L,R));
  if(R>mid) ans=mod(ans+query(rson,L,R));
  return ans; 
}
void Xchange(int x,int y,int z)
{
  while(top[x]!=top[y])
  {
    if(dep[top[x]]<dep[top[y]]) swap(x,y);
    change(1,1,n,id[top[x]],id[x],z); x=f[top[x]]; 
  }
  if(dep[x]>dep[y])swap(x,y);
  change(1,1,n,id[x],id[y],z); 
}
int Xsum(int x,int y)
{
  int ans=0;
  while(top[x]!=top[y])
  {
    if(dep[top[x]]<dep[top[y]]) swap(x,y);
    ans=mod(ans+query(1,1,n,id[top[x]],id[x]));
    x=f[top[x]]; 
  }
  if(dep[x]>dep[y]) swap(x,y);
  ans=mod(ans+query(1,1,n,id[x],id[y])); 
  return ans; 
}
void Ychange(int x,int k)
{
  change(1,1,n,id[x],id[x]+Size[x]-1,k); 
}
int Ysum(int x)
{
  return query(1,1,n,id[x],id[x]+Size[x]-1); 
}
signed main()
{ //luogu nmsl!!
  int m,r; 
  scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
  for(int i=1;i<=n;++i) scanf("%lld",&dat[i]);
  for(int i=1;i<n;++i)
  {
    int x,y;
    scanf("%lld%lld",&x,&y); 
    add(x,y); add(y,x); 
  }
  dfs(r,r); dfs2(r,r); 
  build(1,1,n); 
  for(int i=1;i<=m;++i)
  {
    int opt,x,y,z; scanf("%lld",&opt);
    if(opt==1)
    {
      scanf("%lld%lld%lld",&x,&y,&z);
      Xchange(x,y,z); 
    }
    else if(opt==2)
    {
      scanf("%lld%lld",&x,&y);
      printf("%lld\n",Xsum(x,y)); 
    }
    else if(opt==3)
    {
      scanf("%lld%lld",&x,&z);
      Ychange(x,z); 
    }
    else if(opt==4)
    {
      scanf("%lld",&x);
      printf("%lld\n",Ysum(x)); 
    }
    // for(int j=1;j<=n;++j) printf("%lld ",query(1,1,n,id[j],id[j])) ; 
    // puts(""); 
  }
  return 0 ; 
}
2021/9/29 16:49
加载中...