树链剖分TLE求条,回复即关

P3038 [USACO11DEC] Grass Planting G

CultReborn @ 2023-07-16 17:36:42

笑死了为什么会T掉啊(挠头)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
const int maxm = 400005;
int n,m,s = 1;
//int a[maxn],w[maxn];
int head[maxm],cnt = 1;
int dep[maxn],dfn[maxn],fth[maxn];
int son[maxn],siz[maxn],top[maxn];
int ti = 0;
struct node{
  int to,nxt;
}edge[maxm];
struct SegmentTree{
  int left,right;
  int add,data;
  #define l(p) t[p].left
  #define r(p) t[p].right
  #define a(p) t[p].add
  #define d(p) t[p].data
}t[maxn * 4];
void Input(int u,int v){
  edge[cnt] = {v,head[u]};
  head[u] = cnt++;
}
void Build(int p,int l,int r){
  l(p) = l, r(p) = r;
  if(l == r){
//    d(p) = a[l];
    return;
  }
  int mid = (l + r) / 2;
  Build(p * 2,l,mid);
  Build(p*2+1,mid+1,r);
  d(p) = d(p * 2) + d(p*2+1);
}
void Spread(int p){
  if(a(p)){
    d(p * 2) += a(p) * (r(p * 2) - l(p * 2) + 1);
    d(p*2+1) += a(p) * (r(p*2+1) - l(p*2+1) + 1);
    a(p * 2) += a(p);
    a(p*2+1) += a(p);
    a(p) = 0;
  }
}
void Change(int p,int l,int r,int d){
  if(l <= l(p) && r >= r(p)){
    d(p) += d * (r(p) - l(p) + 1); 
    a(p) += d; return;
  }
  Spread(p);
  int mid = (l(p) + r(p)) / 2;
  if(l <= mid) Change(p * 2,l,r,d);
  if(r > mid)  Change(p*2+1,l,r,d);
  d(p) = d(p * 2) + d(p*2+1);
}
int Ask(int p,int l,int r){
  if(l <= l(p) && r >= r(p))
    return d(p);
  Spread(p); int ans = 0;
  int mid = (l(p) + r(p)) / 2;
  if(l <= mid) ans += Ask(p * 2,l,r);
  if(r > mid)  ans += Ask(p*2+1,l,r);
  return ans;
}
void DFS1(int u,int fa){
  dep[u] = dep[fa] + 1;
  siz[u] = 1;
  fth[u] = fa;
  for(int i = head[u];~i;i = edge[i].nxt){
    int v = edge[i].to;
    if(v != fa){
      DFS1(v,u);
      siz[u] += siz[v];
      if(!son[u] || siz[son[u]] < siz[v])
        son[u] = v;
    }
  }
}
void DFS2(int u,int tp){
  dfn[u] = ++ti;
//  a[ti] = w[u];
  top[u] = tp;
  if(!son[u]) return;
  DFS2(son[u],tp);
  for(int i = head[u];~i;i = edge[i].nxt){
    int v = edge[i].to;
    if(son[u] != v && fth[u] != v)
      DFS2(v,v);
  }
}
void Upd_R(int u,int v,int d){
  int ans = 0;
  while(top[u] != top[v]){
    if(dep[top[u]] < dep[top[v]]) swap(u,v);
    Change(1,dfn[top[u]],dfn[u],d);
    u = fth[top[u]];
  }
  if(dep[u] > dep[v]) swap(u,v);
  Change(1,dfn[u] + 1,dfn[v],d);
}
int Ask_R(int u,int v){
  if(dep[u] > dep[v]) swap(u,v);
  return Ask(1,dfn[v],dfn[v]);
}
//void Upd_T(int u,int d){Change(1,dfn[u],dfn[u] + siz[u] - 1,d);}
//int Ask_T(int u){return Ask(1,dfn[u],dfn[u] + siz[u] - 1);}
int main(){
  scanf("%d %d",&n,&m);
  for(int i = 1;i <= m;++i) head[i] = -1;
  for(int i = 1;i < n;++i){
    int u,v; scanf("%d %d",&u,&v);
    Input(u,v); Input(v,u);
  }
  DFS1(s,0);
  DFS2(s,s);
  Build(1,1,n);
  while(m--){
    string s; int x,y;
    cin >> s >> x >> y;
    switch(s[0]){
      case 'P':Upd_R(x,y,1);break;
      case 'Q':printf("%d\n",Ask_R(x,y));break;
    }
  }
  return 0;
}

by SpeedStar @ 2023-07-16 18:54:27

@CultReborn 感觉你线段树的部分有点问题,changeask 里都少写了两个参数


by CultReborn @ 2023-07-16 19:10:53

@寒烟冷浅暮殇 不至于吧,我就一直这么写线段树的啊QAQ


by SpeedStar @ 2023-07-16 20:57:43

@寒烟冷浅暮殇 你的树剖部分没看出有啥问题,估计是你的线段树常数大了?


by cqbzlyf @ 2023-08-04 18:36:13

标题“调”写成了“条”


|