题意

给定一棵无边权的树,最多只有一个点度数超过2,有两种操作

1)(0 u x d)将距离u节点d距离之内的节点的值加上x

2)(1 u)询问u节点的值

n<=100000,q<=100000

题解

只有一个点度数超过2,那么把它当根,整棵树的形态就是从根开始向下延伸许多链,

将距离u节点d距离之内的节点的值加上x,放在u的子树内(应该叫子链吧?)就是区间修改,可以用线段树或树状数组维护这每一条链,

如果距离u节点d距离之内的节点包括根的话,就要先把u到根的路径加上x,然后把距离根节点d - dis(u,root) 距离之内的其它节点的值加上x,很麻烦

此时需要单独拿一个数据结构维护从根开始延伸的贡献,下标为 i 的数记录深度为 i 的点共同增加过的x之和,于是 “ 把距离根节点d - dis(u,root) 距离之内的其它节点的值加上x ” 就可以在 [1, d - dis(u,root) +1] 上增加x(设根的深度为1),然后在u所在的链上去掉重复的部分

当我们访问一个点的权值时,除了要加上它所在的链上的权值,还要加上对应深度的共同权值。

根要特判。

CODE

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#define MAXN 100005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x)&(x))
//#define int LL
//#pragma GCC optimize(2)
using namespace std;
inline LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + (s - '0');s = getchar();}
return x * f;
}
const int jzm = 1000000007;
int n,m,i,j,s,o,k,root;
int ind[MAXN];
vector<int> g[MAXN];
int dfn[MAXN],d[MAXN],id[MAXN],tl[MAXN],cnt;
int c[MAXN],t[MAXN];
void addt(int x,int y) {while(x <= n) t[x] += y,x += lowbit(x);return ;}
void addc(int x,int y) {while(x <= n) c[x] += y,x += lowbit(x);return ;}
int sumt(int x) {int as=0;while(x>0) as += t[x],x -= lowbit(x);return as;}
int sumc(int x) {int as=0;while(x>0) as += c[x],x -= lowbit(x);return as;}
void dfs(int x,int fa) {
d[x] = d[fa] + 1;
dfn[x] = ++ cnt;
id[cnt] = x;
tl[x] = cnt;
for(int i = 0;i < g[x].size();i ++) {
if(g[x][i] != fa) {
dfs(g[x][i],x);
tl[x] = max(tl[x],tl[g[x][i]]);
}
}
return ;
}
int main() {
n = read();m = read();
root = 1;
for(int i = 1;i < n;i ++) {
s = read();o = read();
ind[s] ++;ind[o] ++;
g[s].push_back(o);
g[o].push_back(s);
if(ind[s] > 2) root = s;
if(ind[o] > 2) root = o;
}
dfs(root,0);
for(int i = 1;i <= m;i ++) {
k = read();
if(!k) {
s = read();k = read();o = read();
if(s == root) {
addc(1,k);
addc(2+o,-k);
// cout<<"ok"<<endl;
}
else {
bool flag = (d[s] <= o+1);
int dis = o - d[s] + 1;
int l,r;
if(flag) l = dfn[s] - d[s] + 2 + dis;
else l = dfn[s] - o;
r = min(tl[s],dfn[s] + o);
if(l <= r) addt(l,k),addt(r+1,-k);
if(flag) addc(1,k),addc(2+dis,-k);
// cout<<"OK"<<endl;
}
}
else {
s = read();
printf("%d\n",sumt(dfn[s]) + sumc(d[s]));
}
}
return 0;
}

Little Girl and Problem on Trees的更多相关文章

  1. Codeforces Round #169 (Div. 2) E. Little Girl and Problem on Trees dfs序+线段树

    E. Little Girl and Problem on Trees time limit per test 2 seconds memory limit per test 256 megabyte ...

  2. Trees on the level(指针法和非指针法构造二叉树)

    Trees on the level Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  3. hdu 1622 Trees on the level(二叉树的层次遍历)

    题目链接:https://vjudge.net/contest/209862#problem/B 题目大意: Trees on the level Time Limit: 2000/1000 MS ( ...

  4. Codeforces Round #169 (Div. 2)

    A. Lunch Rush 模拟. B. Little Girl and Game 因为可以打乱顺序,所以只关心每种数字打奇偶性. 若一开始就是回文,即奇数字母为0或1种,则先手获胜. 若奇数字母大于 ...

  5. CF959C Mahmoud and Ehab and the wrong algorithm 构造

    Mahmoud was trying to solve the vertex cover problem on trees. The problem statement is: Given an un ...

  6. Codeforces Round #473 (Div. 2)

    A. Mahmoud and Ehab and the even-odd game time limit per test 1 second memory limit per test 256 meg ...

  7. [LeetCode] 366. Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  8. HDU p1294 Rooted Trees Problem 解题报告

    http://www.cnblogs.com/keam37/p/3639294.html keam所有 转载请注明出处 Problem Description Give you two definit ...

  9. [LeetCode&Python] Problem 872. Leaf-Similar Trees

    Consider all the leaves of a binary tree.  From left to right order, the values of those leaves form ...

随机推荐

  1. 解决Windows微软账户无法登录

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年8月25日. 将DNS的服务器地址修改为4.2.2.1或者4.2.2.2就可以解决无法登录microsoft账户 ...

  2. docker安装node

    #1.拉取镜像 docker pull node:latest #2.运行 docker run -itd --name node-test --restart=always node #--rest ...

  3. NC50038 kotori和糖果

    NC50038 kotori和糖果 题目 题目描述 kotori共有 \(n\) 块糖果,每块糖果的初始状态是分散的,她想把这些糖果聚在一堆.但她每次只能把两堆糖果合并成一堆. 已知把两堆数量为 \( ...

  4. NC23036 华华听月月唱歌

    NC23036 华华听月月唱歌 题目 题目描述 月月唱歌超级好听的说!华华听说月月在某个网站发布了自己唱的歌曲,于是把完整的歌曲下载到了U盘里.然而华华不小心把U盘摔了一下,里面的文件摔碎了.月月的歌 ...

  5. D2C小练习

    前端智能化现状及未来展望 简介 DEsign: Sketch,Photoshop ,Figma 起源:微软2017年, Design to code code: 前端 核心原理 design----& ...

  6. 活动报名:以「数」制「疫」,解密 Tapdata 在张家港市卫健委数字化防疫场景下的最佳实践

        疫情两年有余,全国抗疫攻防战步履不停.在"动态清零"总方针的指导下,国内疫情防控工作渐趋规范化.常态化.健康码.行程卡.疫情地图.电子哨兵.核酸码.场所码--各类精准防疫手 ...

  7. 在项目中导入lombok依赖自动生成有参,无参 空参 方法的注解

    导入依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok< ...

  8. FileNameFilter过滤器的使用和Lambda优化程序--IO概述(概念&分类)

    FileNameFilter过滤器的使用和Lambda优化程序 public class Demo02Filter { public static void main(String[] args) { ...

  9. centos7 ./configure --prefix error checking for C compiler

    解决方法: 输入以下命令 yum -y install gcc gcc-c++ autoconf automake make

  10. 集合—collection、iterator遍历集合

    一.collection接口 1.collection常用方法 点击查看代码 @Test public void test(){ //contains() Collection coll = new ...