蒟蒻求助树剖板子
查看原帖
蒟蒻求助树剖板子
316827
Temperature_automata楼主2021/3/1 20:35
#include <iostream>
#include <cstdio>


using namespace std ;

#define maxn int(1e5+5)
struct Node {
  int fa ;//父亲
  int son ;//重儿子
  int size ;//大小
  int top ;//当前结点
  int dfn ;//时间戳
  int deep ;//深度
}tree[maxn];//树链剖分
int w[maxn] ;//结点权值dfs序
int tim ;//时间戳计数器tim
int v[maxn] ;//所有结点的权值

struct Edge
{
  int to , nxt ;
}edge[2*maxn] ;
int tot , head[maxn] ;

inline void add(int u , int v) {
  edge[++tot]=(Edge){v,head[u]} ;
  head[u] = tot ;
}

void dfs1(int u,int fa) {
  tree[u].fa = fa ;
  tree[u].deep = tree[fa].deep + 1 ;
  tree[u].size = 1 ;
  int maxsize=-1 ;
  for ( int i = head[u] ; i ; i = edge[i].nxt) 
  {
    int v = edge[i].to ;
    if(v==fa)//回溯了
      continue ;
    dfs1(v,u) ;
    tree[u].size += tree[v].size ;
    if(tree[v].size>maxsize) {
      maxsize = tree[v].size ;
      tree[u].son = v ;
    }
  }
}//第一次dfs:求重儿子、深度、子树大小

void dfs2(int u , int t) {//u:当前结点,t:重链top
  tree[u].dfn = ++tim ;
  tree[u].top = t ;
  w[tim] = v[u] ;
  if(!tree[u].son) return ;//没儿子->bye
  dfs2(tree[u].son,t) ;
  for ( int i = head[u] ; i ; i = edge[i].nxt)
  {
    int v = edge[i].to ;
    if(v==tree[u].fa||v==tree[u].son)
      continue ;
    dfs2(v,v) ;//从轻儿子开始的重链
  }
}//第二次dfs:求时间戳

int mod;

struct node
{
    int l, r, f, val;
} sgt[maxn * 4];//维护w数组线段树
inline int ls(int k) { return k << 1; }
inline int rs(int k) { return k << 1 | 1; }
inline void pushup(int k) { sgt[k].val = (sgt[ls(k)].val + sgt[rs(k)].val) % mod; }
inline void pushdown(int k)
{
    sgt[ls(k)].f += sgt[k].f;
    sgt[rs(k)].f += sgt[k].f;
    sgt[ls(k)].val += (sgt[ls(k)].r - sgt[ls(k)].l + 1) * sgt[k].f % mod;
    sgt[rs(k)].val += (sgt[rs(k)].r - sgt[rs(k)].l + 1) * sgt[k].f % mod;
    sgt[k].f = 0;
}
void build(int l, int r, int k = 1)
{
    sgt[k].l = l, sgt[k].r = r;
    if (l == r)
    {
        sgt[k].val = w[l] % mod;
        return;
    }
    int m = (l + r) >> 1;
    build(l, m, ls(k));
    build(m + 1, r, rs(k));
    pushup(k);
}
void modify(int x, int y, int z, int k = 1)
{
    int l = sgt[k].l, r = sgt[k].r;
    if (x <= l && y >= r)
    {
        sgt[k].f += z;
        sgt[k].val += (r - l + 1) * z;
        sgt[k].val %= mod;
        return;
    }
    if (sgt[k].f)
        pushdown(k);
    int m = (l + r) >> 1;
    if (x <= m)
        modify(x, y, z, ls(k));
    if (y > m)
        modify(x, y, z, rs(k));
    pushup(k);
}
int query(int x, int y, int k = 1)
{
    int l = sgt[k].l, r = sgt[k].r;
    if (x <= l && y >= r)
        return sgt[k].val;
    if (sgt[k].f)
        pushdown(k);
    int sum = 0, m = (l + r) >> 1;
    if (x <= m)
        sum += query(x, y, ls(k));
    if (y > m)
        sum += query(x, y, rs(k));
    return sum % mod;
}//72~132为线段树代码

inline void mson(int x,int z) {
  modify(tree[x].dfn,
         tree[x].dfn+tree[x].size-1,z%mod) ;
}//操作三

inline int qson(int x) {
  return query(tree[x].dfn,
               tree[x].dfn+tree[x].size-1) ;
}//操作四

void mchain(int x , int y,int z) {
  z%=mod ;
  while(tree[x].top!=tree[y].top)//不在同一重链
  {
    if(tree[tree[x].top].deep<
       tree[tree[y].top].deep)
      swap(x,y) ;
    modify(tree[tree[x].top].dfn,tree[x].dfn,z) ;
    x = tree[tree[x].top].fa ;
  }
  if(tree[x].deep>tree[y].deep) 
    swap(x,y) ;
  modify(tree[x].dfn,tree[y].dfn,z) ;
}

int qchain(int x,int y) {
  int res = 0 ;
  while(tree[x].top!=tree[y].top) {
    if(tree[tree[x].top].deep<
       tree[tree[y].top].deep)
       swap(x,y) ;
    res+=query(tree[tree[x].top].dfn,
               tree[x].dfn) ;
    x = tree[tree[x].top].fa ;
  }
  if(tree[x].deep>tree[y].deep)
    swap(x,y) ;
  res+=query(tree[x].dfn,tree[y].dfn) ;
  return res%mod ;
}

int main ( ) {
  #ifndef ONLINE_JUDGE
    // freopen("input.in","r",stdin) ;
    // freopen("output.out","w",stdout) ;
  #endif

  int n , m , r ;
  cin >> n >> m >> r >> mod ;
  for ( int i = 1 ; i <= n ; i++ ) {
    cin >> v[i] ;
    v[i]%=mod ;
  }
  for ( int i = 1 ; i < n ; i ++ ) {
    int u , v ;
    cin >> u >> v ;
    add(u,v) ;
    add(v,u) ;
  }
  dfs1(r,r) ;
  dfs2(r,r) ;
  build(1,n) ;
  while(m--) {
    int opt , x , y , z ;
    cin >> opt ;
    switch(opt) {
      case 1:cin >> x >> y >> z ;
             mchain(x,y,z) ;
             break ;
      case 2:cin >> x >> y ;
             cout << qchain(x,y) << endl ;
             break ;
      case 3:cin >> x >> z ;
             mson(x,y) ;
             break ;
      case 4:cin >> x ;
             cout << qson(x) << endl ;
             break ;
    }
  }
  
  #ifndef ONLINE_JUDGE
    system("pause") ;
  #endif
    return 0 ;
}

样例WA了,求助求助求助(拜托

2021/3/1 20:35
加载中...