题意

给定一棵无边权的树,最多只有一个点度数超过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. 整数分解、for循环阶乘

    整数分解 整数分解是什么呢??我们可以这样理解 我们写一个 3位数求出它的个位十位和百位 . 那么我们来写一个小的测试来看一下! public static void main(String[] ar ...

  2. ngx_http_fastcgi_module 的那些事

    是什么? 顾名思义,是Nginx用来处理FastCGI的模块.FastCGI是什么?这个以后再讲,可以说的是现在LNMP架构里面,PHP一般是以PHP-CGI的形式在运行,它就是一种FastCGI,我 ...

  3. .NET Core 企业微信回调配置

    1.配置API接收 2.下载加密解密库 地址:https://developer.work.weixin.qq.com/devtool/introduce?id=36388,也可以复制下面的代码 2. ...

  4. React中render Props模式

    React组件复用 React组件复用的方式有两种: 1.render Props模式 2.高阶组件HOC 上面说的这两种方式并不是新的APi. 而是利用Raect自身的编码特点,演化而来的固定编码写 ...

  5. 第六章、PXE高效网络装机、Kickstart无人值守安装

    目录 一.部署PXE远程安装服务 1PXE定义 2PXE服务优点 3搭建网络体系前提条件 4PXE实现过程讲解 二.搭建PXE远程安装服务器 三.Kickstart无人值守安装 一.部署PXE远程安装 ...

  6. Tensor的创建和维度的查看

    常见的Tensor创建方法 1,基础Tensor函数:torch.Tensor(2,2)32位浮点型 2,指定类型: torch.DoubleTensor(2,2)64位浮点型 3,使用python的 ...

  7. <%= %> <%- %> <% %>是什么意思?

    .ejs文件后缀的数据渲染,这是服务器端的.把 .html改成 .ejs, (1)<%= %>相当于html中的innerTEXT,导出不包含标签 . (2)<%- %>相当于 ...

  8. django--ORM表的多对一关系

    多对一关系是什么 Django使用django.db.models.ForeignKey定义多对一关系. ForeignKey需要一个位置参数:与该模型关联的类  class Info(models. ...

  9. 高精度10m/30米NPP净初级生产力分布数据

    数据下载链接:百度云下载链接​ 引言 第一性生产力是绿色植物呼吸后所剩下的单位面积单位时间内所固定的能量或所生产的有机物质,即是总第一性生产量减去植物呼吸作用所剩下的能量或有机物质.多种卫星遥感数据反 ...

  10. SpringBoot自定义starter开发分布式任务调度实践

    概述 需求 在前面的博客<Java定时器演进过程和生产级分布式任务调度ElasticJob代码实战>中,我们已经熟悉ElasticJob分布式任务的应用,其核心实现为elasticjob- ...