Wa 30pts 树链剖分求调
  • 板块P3401 洛谷树
  • 楼主Daniel_yao
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/16 08:35
  • 上次更新2024/10/16 14:00:29
查看原帖
Wa 30pts 树链剖分求调
519573
Daniel_yao楼主2024/10/16 08:35
#include<bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
#define int long long
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)

using namespace std;

const int N = 2e5 + 10, M = 11;

struct Node {
  int l, r, cnt[M][2], tag;
} t[N << 2];

struct node {
  int v, w, nx;
} e[N << 1];

int cnt0[M], cnt1[M];

int n, q, tot, h[N], dep[N], siz[N], fa[N], son[N], w[N], top[N], dfn[N], id[N], idx, s[N];

void add(int u, int v, int W)  {
  e[++tot] = (node){v, W, h[u]};
  h[u] = tot;
}

void dfs(int x, int f) {
  dep[x] = dep[f] + 1, siz[x] = 1;
  fa[x] = f;
  int maxi = 0;
  for (int i = h[x]; i; i = e[i].nx) {
    int y = e[i].v;
    if(y == fa[x]) continue;
    w[y] = e[i].w;
    s[y] = s[x] ^ w[y];
    dfs(y, x);
    siz[x] += siz[y];
    if(maxi < siz[y]) {
      maxi = siz[y];
      son[x] = y;
    }
  }
}

void dfs1(int x, int tp) {
  top[x] = tp;
  dfn[x] = ++idx;
  id[idx] = x;
  if(son[x]) dfs1(son[x], tp);
  for (int i = h[x]; i; i = e[i].nx) {
    int y = e[i].v;
    if(y == fa[x] || y == son[x]) continue;
    dfs1(y, y);
  }
}

void pushup(int p) {
  For(i,0,10) {
    t[p].cnt[i][0] += t[ls].cnt[i][0];
    t[p].cnt[i][1] += t[ls].cnt[i][1];
    t[p].cnt[i][0] += t[rs].cnt[i][0];
    t[p].cnt[i][1] += t[rs].cnt[i][1]; 
  }
}

void pushdown(int p) {
  if(t[p].tag) {
    For(i,0,10) {
      if((t[p].tag >> i) & 1) {
        swap(t[ls].cnt[i][0], t[ls].cnt[i][1]);
        swap(t[rs].cnt[i][0], t[rs].cnt[i][1]);
      }
    }
    t[ls].tag ^= t[p].tag;
    t[rs].tag ^= t[p].tag;
    t[p].tag = 0;
    return ;
  }
}

void build(int p, int l, int r) {
  t[p].l = l, t[p].r = r, t[p].tag = 0;
  if(l == r) {
    For(i,0,10) {
      t[p].cnt[i][(s[id[l]] >> i) & 1]++;
    }
    return ;
  }
  int mid = l + r >> 1;
  build(ls, l, mid);
  build(rs, mid + 1, r);
  pushup(p);
}

int query(int op, int k, int p, int l, int r) {//op:0/1 位数为0/1,k:0~10 第几位
  if(l <= t[p].l && t[p].r <= r) {
    return t[p].cnt[k][op];
  }
  pushdown(p);
  int mid = t[p].l + t[p].r >> 1, ans = 0;
  if(l <= mid) ans += query(op, k, ls, l, r);
  if(r > mid) ans += query(op, k, rs, l, r);
  return ans;
}

void update(int p, int l, int r, int k) {
  if(l <= t[p].l && t[p].r <= r) {
    For(i,0,10) {
      if((k >> i) & 1) {
        swap(t[p].cnt[i][0], t[p].cnt[i][1]);
      }
    }
    t[p].tag ^= k;
    return ;
  }
  pushdown(p);
  int mid = t[p].l + t[p].r >> 1;
  if(l <= mid) update(ls, l, r, k);
  if(r > mid) update(rs, l, r, k);
  pushup(p);
}

int qry(int x, int y) {
  int ans = 0;
  memset(cnt0, 0, sizeof cnt0);
  memset(cnt1, 0, sizeof cnt1);
  while(top[x] != top[y]) {
    if(dep[top[x]] < dep[top[y]]) swap(x, y);
    For(i,0,10) {
      cnt0[i] += query(0, i, 1, dfn[top[x]], dfn[x]);
      cnt1[i] += query(1, i, 1, dfn[top[x]], dfn[x]);
    }
    x = fa[top[x]];
  }
  if(dep[x] < dep[y]) swap(x, y);
  For(i,0,10) {
    cnt0[i] += query(0, i, 1, dfn[y], dfn[x]);
    cnt1[i] += query(1, i, 1, dfn[y], dfn[x]);
  }
  For(i,0,10) {
    ans += (1 << i) * cnt0[i] * cnt1[i];
  }
  return ans;
}

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n >> q;
  For(i,1,n-1) {
    int u, v, W;
    cin >> u >> v >> W;
    add(u, v, W);
    add(v, u, W);
  }
  dfs(1, 0);
  dfs1(1, 1);
  build(1, 1, idx);
  while(q--) {
    int op, u, v, k;
    cin >> op >> u >> v;
    if(op == 1) {
      cout << qry(u, v) << '\n';
    } else {
      cin >> k;
      if(dep[u] < dep[v]) swap(u, v);
      update(1, dfn[u], dfn[u] + siz[u] - 1, w[u] ^ k);
      w[u] = k;
    }
  }
  return 0;
}

提交记录

已知第一个数据点

操作为:

2 26 12 433
2 84 6 647
1 31 46
1 28 84
1 49 15

输出为:

93721
119530
1490

本人代码输出为:

265782
119530
1490

怀疑是标记下传出问题,但是没有找到问题所在。

2024/10/16 08:35
加载中...