Codeforces 396C
题意略。
思路:
将树上的节点编好dfs序,然后就可以用树状数组区间修改点查询了。
我们用 lft[v] 和 rht[v]来表示v的子树在dfs序中的左端和右端,这样才方便我们对树状数组的操作。
其实这个题目的问题在于每个点在修改时,修改的值不是一定的,会发生变化。
我是将加上的值和减去的值分开了。
开两个树状数组,一个记录加:在我们进行加操作的时候,加上的值是x + deep[v] * k。
一个记录减:在我们进行减操作的时候,减去的值就是k。
最后在获取答案的时候,ans = sum(v,0) - deep[v] * sum(v,1)。
详见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e5 + ;
const LL mod = 1e9 + ; int lft[maxn],rht[maxn],n,q,cnt;
LL deep[maxn],BIT[][maxn];
vector<int> graph[maxn]; void dfs(int cur,int d){
lft[cur] = ++cnt;
deep[cur] = d;
for(int i = ;i < graph[cur].size();++i){
int v = graph[cur][i];
dfs(v,d + );
}
rht[cur] = cnt;
}
int lowbit(int k){
return (k & -k);
}
void add(int pos,LL val,int idx){
while(pos <= n){
BIT[idx][pos] += val;
BIT[idx][pos] %= mod;
pos += lowbit(pos);
}
}
LL sum(int pos,int idx){
LL ret = ;
while(pos > ){
ret += BIT[idx][pos];
pos -= lowbit(pos);
ret %= mod;
}
return ret;
} int main(){
scanf("%d",&n);
int pi;
for(int i = ;i <= n;++i){
scanf("%d",&pi);
graph[pi].push_back(i);
}
dfs(,);
scanf("%d",&q);
for(int i = ;i < q;++i){
int type;
scanf("%d",&type);
if(type == ){
int v;
LL x,k;
scanf("%d%lld%lld",&v,&x,&k);
LL val = (x + deep[v] * k) % mod;
add(lft[v],val,);
add(rht[v] + ,-val,);
add(lft[v],k,);
add(rht[v] + ,-k,);
}
else{
int v;
scanf("%d",&v);
int pos = lft[v];
LL part1 = sum(pos,);
LL part2 = sum(pos,);
part2 = part2 * deep[v] % mod;
LL ans = ((part1 - part2) % mod + mod) % mod;
printf("%lld\n",ans);
}
}
return ;
}
Codeforces 396C的更多相关文章
- CodeForces 396C On Changing Tree
On Changing Tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...
- CodeForces 396C 树状数组 + DFS
本主题开始看到以为段树或树状数组,但是,对于一个节点的有疑问的所有子节点的加权,这一条件被视为树的根,像 然后1号是肯定在第一层中,然后建立一个单向侧倒查,然后记录下来 其中每个节点 层,终于 两个节 ...
- CodeForces - 396C On Changing Tree(树状数组)
题目大意 给定一棵以1为根的树,初始时所有点为0 给出树的方式是从节点2开始给出每一个点的父亲 然后是 $m$ 次操作,分为两种 $1 v,k,x$ 表示在以v为根的子树中的每一个点上添加 $x-i* ...
- Codeforces 396C (DFS序+线段树)
题面 传送门 题目大意: 给定一棵树,每个点都有权值,边的长度均为1,有两种操作 操作1:将节点u的值增加x,并且对于u的子树中的任意一个点v,将它的值增加x-dist(u,v)*k, dist(u, ...
- CDQ分治题目小结
CDQ分治属于比较特殊的一类分治,许多问题转化为这类分治的时候,时空方面都会有很大节省,而且写起来没有这么麻烦. 这类分治的特殊性在于分治的左右两部分的合并,作用两部分在合并的时候作用是不同的,比如, ...
- CQD(陈丹琦)分治 & 整体二分——专题小结
整体二分和CDQ分治 有一些问题很多时间都坑在斜率和凸壳上了么--感觉斜率和凸壳各种搞不懂-- 整体二分 整体二分的资料好像不是很多,我在网上找到了一篇不错的资料: 整体二分是个很神的东西 ...
- codeforces396C
On Changing Tree CodeForces - 396C You are given a rooted tree consisting of n vertices numbered fro ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
随机推荐
- python课堂整理6---字典
一.字典 dict info = {"k1" : "v1", "k2" : "v2"} 以键值对形式组成字典 字典里的 ...
- python课堂整理1
1.变量 变量只能由字母.数字.下划线组成 特例:1.变量不能用数字开头 2.不能是python的关键字 3.最好不要和python内置的东西重复 让变量名有意义 些 python3的关键字 ...
- WebGL中深度碰撞方法总结
z-fighting问题是三维渲染中常见的问题,本文根据实际工作中遇到的一些场景,进行了系统的总结 一个实际工作中的问题 当两个面离得太近就会发生深度碰撞问题,比如: 遇到深度检测问题,最重要的是先搞 ...
- javascript基础学习第二天
ECMASCRIPT(语法标准) 1. 能够写出简单的逻辑程序代码 2. 变量,数据类型,运算符,条件判断语句,循环语法,数组,对象,函数 1. 赋值运算符 = 将'='右侧的结果赋值给左侧的变量 a ...
- 负载分配—DNS的域名解析
DNS(Domain Name System)是因特网的一项服务,它作为域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网.人们在通过浏览器访问网站时只需要记住网站的域名即可,而不需 ...
- mybatis动态插入数据库
<insert id="dynamicAddUser"> insert into t_user <!-- trim 对所有的表中列名 进行动态处理 --> ...
- TestNg中的断言你真的了解吗
前言 在执行自动化测试脚本的时候,我们需要自动判断测试脚本执行完成后的实际结果是否与预期结果一致,这个时候就需要在程序运行之前写入断言,判断当前程序执行后是否正常. 关于TestNG断言分为两种: 软 ...
- PHP后门***详解
说起php后门***我就心有愉季啊前不久一个站就因不小心给人注入了然后写入了小***这样结果大家知道的我就不说了下面我来给大家收集了各种php后门***做法大家可参考. php后门***对大家来说一点 ...
- Wtm携手LayUI -- .netcore 开源生态我们是认真的!
经过WTM团队和LayUI团队多次深入协商,双方于2019年7月29日在北京中国国际展览中心正式达成战略合作意向, 双方签署了战略合作框架协议,LayUI团队承诺使用WTM框架的任何项目都可以免费使用 ...
- Hadoop 系列(三)—— 分布式计算框架 MapReduce
一.MapReduce概述 Hadoop MapReduce 是一个分布式计算框架,用于编写批处理应用程序.编写好的程序可以提交到 Hadoop 集群上用于并行处理大规模的数据集. MapReduce ...