【每日一题】dfs序专题 求和

求和

https://ac.nowcoder.com/acm/problem/204871

Description

图片说明

Solution

以前牛客小白赛里也有类似的题目,简单地讲,在树上进行子树区间上的修改和求和问题可以转化为我们熟悉的序列问题。
思路:处理出dfs序,然后找到每个节点的子树区间在哪个访问内,剩下的就是树状数组单点修改,区间求和的操作啦。
时间复杂度:O(nlogn)

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
ll T[N];
int a[N];
int lowbit(int x) {
  return x & (-x);
}
void update(int x, int add) {
  while(x < N) {
    T[x] += add;
    x += lowbit(x);
  }
}
ll query(int x) {
  ll res = 0;
  while(x) {
    res += T[x];
    x -= lowbit(x);
  }
  return res;
}
int L[N], R[N], rk[N];
struct Edge {
  int v, nextz;
}edge[N << 1];
int head[N], tot;
void addedge(int u, int v) {
  edge[tot].v = v;
  edge[tot].nextz = head[u];
  head[u] = tot++;
}
int cnt = 0;
void dfs(int u, int par) {
  rk[u] = ++cnt;
  L[u] = cnt;
  for(int i = head[u]; ~i; i = edge[i].nextz) {
    int v = edge[i].v;
    if(v == par) continue;
    //cout << u << ' ' << v <<' ' << par << '\n';
    dfs(v, u);
  }
  R[u] = cnt;
}
int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  memset(head, -1, sizeof(head));
  int n, m, k; cin >> n >> m >> k;
  for(int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for(int i = 1; i <= n - 1; i++) {
    int u, v; cin >> u >> v;
    addedge(u, v); addedge(v, u);
  }
  dfs(k, -1);
  //cout << "flag" << '\n';
  for(int i = 1; i <= n; i++) {
    //cout << i << ' ' << rk[i] << '\n';
    update(rk[i], a[i]);
  }
  //cout << "flag" << '\n';
  while(m--) {
    int op, ql, qr; cin >> op >> ql;
    if(op == 1) {
      cin >> qr;
      update(rk[ql], qr);
    } else {
      //cout << ql << ' ' << R[ql] << ' ' << L[ql] << '\n';
      cout << query(R[ql]) - query(L[ql] - 1) << "\n";
    }
  }
  return 0;
}
Kurisu与牛客的每日一题 文章被收录于专栏

每日一题

全部评论

相关推荐

10-23 16:33
门头沟学院 Java
本人某中9本科,成绩中等,目前没科研没实习,目前后端学到了javaWeb,开始没定好方向,在学国外课程,走工程路线起步有点晚了,到这个时间点了还在学JavaWeb,顿感迷茫,不知道是坚持走下去还是寒假去准备考研。考研这个路弄得我还是心痒痒的,因为从众考研的人也不在少数,所以会有这方面的心理安慰吧,就是“不行我可以去考研啊”,而且意味着三年的缓冲,为了复试还有积攒经验美化简历,其实现在也可以去申入实验室打杂;就业可能意味着多些工作经验,工程岗应该到后面还是经验大于学历?还是有点迷茫了,求助好心人有无路线启发
千千倩倩:同27给点建议,现在这个时间点可以快速看完外卖和点评,不用跟着敲,但一定要在看的时候总结每个部分的整个业务流程,对其中的实现有一个大概的印象。然后直接开始看八股,刷算法。八股和算法最好还是在项目学习中穿插着看。如果计算机基础,算法这些基础好,加上每天刻苦学习,两周可以达到勉强能面试的水平,到时候就直接海投中小厂,在约面和面试的过程中不断巩固知识。没找到实习也没关系,就当积累经验。再沉淀一波直接明年三月开始投暑期,毕竟是9本,总是有面试机会的,只要你这三个月不懈怠,面试发挥得一定不错,只要拿到一个中,大厂暑期实习,秋招就有竞争力了。总得而言,现在还有机会,但是时间非常紧张,需要你结合自己情况考虑,共勉
你会选择考研还是直接就业
点赞 评论 收藏
分享
迷茫的大四🐶:价格这么低都能满了?
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务