NC23051 华华和月月种树

华华和月月种树

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

华华和月月种树

题目地址:

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

基本思路:

我们考虑先离线,将树建出来,然后在序上用差分树状数组维护,
但是在这样做的过程中,对于每次的操作二,有些实际还没有被加入的点也被算了权值,
所以我们在每次新加点的时候记录一下,这个点被加进来的时候已经有多少权值了,
很明显这部分权值是无效的,我们在之后的查询里去除这部分就是了。

参考代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define int long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)
#define INF 0x3f3f3f3f

inline int read() {
  int x = 0, neg = 1; char op = getchar();
  while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
  while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
  return neg * x;
}
inline void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}

const int maxn = 4e5 + 10;
int m,op[maxn],pos[maxn],a[maxn],w[maxn];
int L[maxn],R[maxn],tot;
vector<int> G[maxn];
void dfs(int u,int par){
  L[u] = ++tot;
  for(auto to : G[u]){
    if(to == par) continue;
    dfs(to,u);
  }
  R[u] = tot;
}
struct BIT{
    int t[maxn << 2];
    int lowbit(int x){
      return x & (-x);
    }
    void clear(){
      memset(t,0,sizeof(t));
    }
    int sum(int x){
      int res = 0;
      while(x){
        res += t[x];
        x -= lowbit(x);
      }
      return res;
    }
    void update(int x,int v){
      while(x <= tot + 1){
        t[x] += v;
        x += lowbit(x);
      }
    }
}bit;
signed main() {
  m = read();
  int cnt = 0;
  rep(i, 1, m) {
    op[i] = read(), pos[i] = read();
    if (op[i] == 2) a[i] = read();
    else if (op[i] == 1) {
      G[pos[i]].pb(++cnt);
      G[cnt].push_back(pos[i]);
      a[i] = cnt; // 记录一下这次加入的是哪个点;
    }
  }
  dfs(0, -1);
  bit.clear();
  for (int i = 1; i <= m; i++) {
    if (op[i] == 1) {
      w[L[a[i]]] = bit.sum(L[a[i]]); //在这之前被计算的权值是无效的,因为之前还不存在这个点;
    } else if (op[i] == 2) {
      bit.update(L[pos[i]], a[i]); // 在树状数组上差分;
      bit.update(R[pos[i]] + 1, -a[i]);
    } else {
      int ans =  bit.sum(L[pos[i]]) - w[L[pos[i]]]; // 总的权值减去无效的部分;
      print(ans);
      puts("");
    }
  }
  return 0;
}
全部评论

相关推荐

2025-12-24 15:25
已编辑
门头沟学院 前端工程师
是腾讯的csig腾讯云,前天晚上九点突然打电话约面,激动的通宵学了一晚上,第二天状态很差改了今天(以后再也不通宵学习了)感觉自己浪费了面试官一个半小时单纯手写+场景,无八股无项目无算法,打击真的很大,全是在面试官提醒的情况下完成的,自己技术方面真的还是有待提高,实力匹配不上大厂和已经面试的两个公司完全不一样,很注重编码能力和解决问题的能力,然而我这两个方面都很薄弱,面试官人很好很耐心的等我写完题目,遇到瓶颈也会提醒我,写不出题也会很耐心的跟我讲解好感动,到最后面试结束还安慰我打算把下周最后一场面试面完之后就不面啦,如果能去实习还是很开心,但是最重要的还是好好努力提高技术以下是面经第一题//&nbsp;实现一个解析&nbsp;url&nbsp;参数的函数function&nbsp;parseUrl(urlStr)&nbsp;{//&nbsp;TODO}parseUrl('*********************************************');//&nbsp;返回&nbsp;{a:&nbsp;1,&nbsp;b:&nbsp;2,&nbsp;c:&nbsp;3}追问:在链接里见过什么部分?用&nbsp;hash&nbsp;路由的话放在哪第二题//&nbsp;考虑有一个异步任务要执行,返回&nbsp;Promise,这个任务可能会失败,请实现&nbsp;retry&nbsp;方法,返回新方法,可以在失败后自动重试指定的次数。/***&nbsp;异步任务重试*&nbsp;@param&nbsp;task&nbsp;要执行的异步任务*&nbsp;@param&nbsp;times&nbsp;需要重试的次数,默认为&nbsp;3&nbsp;次*/function&nbsp;retry(task,&nbsp;times&nbsp;=&nbsp;3)&nbsp;{//&nbsp;TODO:&nbsp;请实现}//&nbsp;---------------测试示例&nbsp;----------------//&nbsp;原方法const&nbsp;request&nbsp;=&nbsp;async&nbsp;(data)&nbsp;=&gt;&nbsp;{//&nbsp;模拟失败if&nbsp;(Math.random()&nbsp;&lt;&nbsp;0.7)&nbsp;{throw&nbsp;new&nbsp;Error('request&nbsp;failed');}const&nbsp;res&nbsp;=&nbsp;await&nbsp;fetch(&#39;https://jsonplaceholder.typicode.com/posts&#39;,&nbsp;{method:&nbsp;'POST',body:&nbsp;JSON.stringify(data),});return&nbsp;res.json();}//&nbsp;新的方法const&nbsp;requestWithRetry&nbsp;=&nbsp;retry(request);//&nbsp;使用async&nbsp;function&nbsp;run()&nbsp;{const&nbsp;res&nbsp;=&nbsp;await&nbsp;requestWithRetry({&nbsp;body:&nbsp;'content'&nbsp;});console.log(res);}run();第三题就是给&nbsp;retry&nbsp;函数添加类型注释,用到泛型第四题:在组件库中将&nbsp;Alert&nbsp;用&nbsp;api&nbsp;的形式实现(应该就是&nbsp;message&nbsp;这个组件)怎么渲染到一个浮层里而不是原地渲染出来
不知道怎么取名字_:技术这个东西,太杂了,而且要下功夫的
查看5道真题和解析
点赞 评论 收藏
分享
码农索隆:以下是我以我微薄的认知提供的建议: 1.考个教师资格证,去当体育考试。 2.去健身房当健身教练(因为在我印象里面体育生身材都不错)。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

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