F - Change FZU - 2277 (DFS序+线段树)
题目链接:
F - Change
题目大意:
题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作
(1) 1 v k x : a[v] += x, a[v '] += x – k(v '为v的儿子), a[v ' '] += x – 2 * k(v ' '是v '的儿子) ... ;
(2) 2 v : 输出a[v] % (1e9 + 7);
具体思路:dfs序+线段树
a[v'']=a[v'']+x-k*(depth[v'']-depth[v])=a[v'']+x-k*depth[v"]+k*depth[v]=(a[v"]+k*depth[v]) - k*depth[v""].
第一个括号里面用一个线段树维护,第二个括号里面用另一个线段树维护就可以了。
具体求值的时候:对于一次增加操作,节点x增加的值其实就是x-(deep[x]-deep[v])*k。(deep[v]为该次修改的根节点)。
AC代码:
#include<iostream>
#include<stdio.h>
#include<vector>
#include<cstring>
using namespace std;
# define ll long long
# define lson l,mid,rt<<
# define rson mid+,r,rt<<|
const int maxn = 3e5+;
const int mod =1e9+;
ll tree1[maxn<<],tree2[maxn<<];
int dfsord,n;
vector<int>edge[maxn];
int st[maxn],ed[maxn],depth[maxn];
int Scan()
{
int res = , ch, flag = ;
if((ch = getchar()) == '-')
flag = ;
else if(ch >= '' && ch <= '')
res = ch - '';
while((ch = getchar()) >= '' && ch <= '' )
res = res * + ch - '';
return flag ? -res : res;
} ll Scan_l()
{
ll res = ;
int ch, flag = ;
if((ch = getchar()) == '-')
flag = ;
else if(ch >= '' && ch <= '')
res = ch - '';
while((ch = getchar()) >= '' && ch <= '' )
res = res * + ch - '';
return flag ? -res : res;
}
void init()
{
for(int i=; i<n; i++)
{
edge[i].clear();
}
dfsord=;
memset(tree1,,sizeof(tree1));
memset(tree2,,sizeof(tree2));
}
void dfs(int cur,int fa,int dep)
{
st[cur]=ed[cur]=++dfsord;
depth[dfsord]=dep+;
for(int i=; i<edge[cur].size(); i++)
{
int to=edge[cur][i];
if(to==fa)
continue;
dfs(to,cur,dep+);
}
ed[cur]=dfsord;
}
void down(int rt)
{
tree1[rt<<]=(tree1[rt<<]+tree1[rt]+mod)%mod;
tree1[rt<<|]=(tree1[rt<<|]+tree1[rt]+mod)%mod;
tree2[rt<<]=(tree2[rt<<]+tree2[rt]+mod)%mod;
tree2[rt<<|]=(tree2[rt<<|]+tree2[rt]+mod)%mod;
tree1[rt]=,tree2[rt]=;
}
void update(int l,int r,int rt,int L,int R,ll val1,ll val2)
{
if(L<=l&&R>=r)
{
tree1[rt]=(tree1[rt]+val1+mod)%mod;
tree2[rt]=(tree2[rt]+val2+mod)%mod;
return ;
}
down(rt);
int mid=(l+r)>>;
if(L<=mid)
update(lson,L,R,val1,val2);
if(R>mid)
update(rson,L,R,val1,val2);
}
ll ask(int l,int r,int rt,int pos)
{
if(l==r)
{
return (tree1[rt]+tree2[rt]*depth[pos]%mod+mod)%mod;
}
int mid=(l+r)>>;
down(rt);
if(pos<=mid)
return ask(lson,pos);
else
return ask(rson,pos);
}
int main()
{
int T,tmp;
T=Scan();
while(T--)
{
n=Scan();
init();
for(int i=; i<=n; i++)
{
tmp=Scan();
edge[tmp].push_back(i);
}
int m;
dfs(,,);
m=Scan();
while(m--)
{
int op,v;
ll x,k;
op=Scan();
if(op==)
{
v=Scan();
x=Scan_l();
k=Scan_l();
update(,n,,st[v],ed[v],x+k*depth[st[v]],-k);
}
else
{
v=Scan();
ll ans=ask(,n,,st[v]);
ans=(ans%mod+mod)%mod;
printf("%lld\n",ans);
}
}
}
return ;
}
F - Change FZU - 2277 (DFS序+线段树)的更多相关文章
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- CodeForces 877E Danil and a Part-time Job(dfs序+线段树)
Danil decided to earn some money, so he had found a part-time job. The interview have went well, so ...
- 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
- 【cf343】D. Water Tree(dfs序+线段树)
传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...
- BZOJ 3252题解(贪心+dfs序+线段树)
题面 传送门 分析 此题做法很多,树形DP,DFS序+线段树,树链剖分都可以做 这里给出DFS序+线段树的代码 我们用线段树维护到根节点路径上节点权值之和的最大值,以及取到最大值的节点编号x 每次从根 ...
随机推荐
- SpringCloud第二弹(高可用Eureka+Ribbon负载均衡)
先建立父工程 .. ..一路next 搭建注册中心(需要建立三个工程,端口不一样) .. .. .. 修改入口类 package com.cloud.eurekaserver1111; import ...
- linux driver ------ 字符设备驱动 之 “ 创建设备节点流程 ”
在字符设备驱动开发的入门教程中,最常见的就是用device_create()函数来创建设备节点了,但是在之后阅读内核源码的过程中却很少见device_create()的踪影了,取而代之的是device ...
- 抛开jQuery,拾起原生JS的DOM操作
常用的JS-DOM操作与jQuery的对比 jQuery用多了,还是需要来熟练熟练原生JS的操作,不然写JS都快离不开jQuery了 目录 1. 获取DOM 2. 创建DOM 3. 添加DOM 4. ...
- #1479 : 三等分(树形DP)
http://hihocoder.com/problemset/problem/1479 #1479 : 三等分 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最 ...
- storm集群配置
环境:centos6.4软件:jzmq-master-----java与c++通讯的桥梁,有了它,就可以使用zeromp了storm-0.8.2zeromq-2.1.7-----号称史上最牛逼的消息队 ...
- Spring Boot笔记六:Thymeleaf介绍
目录 什么是thymeleaf? 创建最简单的thymeleaf thymeleaf语法 什么是thymeleaf? thymeleaf是一个模板引擎,是用来在Spring Boot中代替JSP的 引 ...
- .net 数据绑定gridview 和Repeater 序号,Container.ItemIndex
gridview <asp:TemplateColumn HeaderText="编号"> <ItemTemplate> &l ...
- python -- leetcode 刷题之路
第一题 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], tar ...
- spingBoot整合mybatis+generator+pageHelper
spingBoot整合mybatis+generator+pageHelper 环境/版本一览: 开发工具:Intellij IDEA 2018.1.4 springboot: 2.0.4.RELEA ...
- GeoGlobe Server运维
本篇博文简单记录鄙人在管理和维护GeoGlobe Server中,遇到的一些问题以及可行的解决方案 1 关于启动内存 Server默认的启动内存是256M,当服务比较多的时候,启动就会很慢.我们可以修 ...