题意

给定一棵无边权的树,最多只有一个点度数超过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. 验证cuda和cudnn是否安装成功(转载)

    本人cuda安装目录: 当然cuda安装目录也可默认:此处为方便安装不同cuda版本,所以单独建了文件夹. 转载自:https://zhuanlan.zhihu.com/p/139668028 安装完 ...

  2. Ubuntu,CenOS等Linux系统更改环境变量方法,以安装anaconda为例

    [环境配置的原因] 在windows系统下,很多软件的安装都需要设置环境变量,比如安装JAVA JDK.如果不安装环境变量,在非软件安装的目录下运行javac命令,将会报告"找不到文件&qu ...

  3. Tarjan算法模板(USACO03FALL受欢迎的牛)

    好文章 #include<bits/stdc++.h> using namespace std; const int N = 10010, M = 50010; int n, m; int ...

  4. 我的开源之路:耗时 6 个月发布线程池框架,GitHub 1.7k Star!

    文章首发在公众号(龙台的技术笔记),之后同步到掘金和个人网站:xiaomage.info Hippo4J 线程池框架经过 6 个多月的版本迭代,2022 年春节当天成功发行了 1.0.0 RELEAS ...

  5. BUUCTF-qr

    qr 签到题

  6. 4种方法教你如何查看java对象所占内存大小

    摘要:本文讲述4种查看java对象所占内存大小的方法 本文分享自华为云社区<查看java对象所占内存大小>,作者:xiewenci. 计算java对象所占内存大小 1.使用jdk8自带AP ...

  7. 基于mysql实现group by取各分组最新一条数据

    准备数据 SQL语句 SELECT * FROM admin WHERE id IN ( SELECT MAX( id ) FROM admin GROUP BY order_id ); 查询结果:

  8. [ARC096C] Everything on It 补题记录

    题目链接 题目大意: 对于集合 \(\{1,2,\dots,n\}\) ,求它的子集族中,有多少个满足: 任意两个子集互不相同: \(1,2,\dots,n\) 都在其中至少出现了 \(2\) 次. ...

  9. 《Domain Agnostic Learning with Disentangled Representations》ICML 2019

    这篇文章是ICML 2019上一篇做域适应的文章,无监督域适应研究的问题是如何把源域上训练的模型结合无lable的目标域数据使得该模型在目标域上有良好的表现.之前的研究都有个假设,就是数据来自哪个域是 ...

  10. APISpace 让你快速获取名言警句

    名言警句,是指一些名人说的.写的.历史纪录的.经过实践所得出的结论或建议.警示的比较有名的言语.名言警句易于留传.   名言警句API,涵盖人生.励志等多个方面.   APISpace 有很多免费通用 ...