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 每次从根 ...
随机推荐
- javascript学习笔记二
1.js的string对象 **创建 String对象 *** var str = "abc"; **方法 和 属性(文档) *** 属性 length : 字符串的长度 ***方 ...
- 关于处理iis8.0中设置Request.BinaryRead 不允许操作的解决方法
iis6.0解决方案: 起初我刚开始上传的是小文件运行都是正常的,后来我弄个文件大点的上传看程序运行怎么样?就上面的问题,在网上搜索正好找到跟我一样的问题,拿过来自己记录下.其中行62指的是:oUpF ...
- FFT的一种迭代实现
struct Complex { double x,y; Complex(double x1=0.0 ,double y1=0.0) { x=x1; y=y1; } Complex operator ...
- (sort 排序)P1583 魔法照片 洛谷
题目描述 一共有n(n≤20000)个人(以1--n编号)向佳佳要照片,而佳佳只能把照片给其中的k个人.佳佳按照与他们的关系好坏的程度给每个人赋予了一个初始权值W[i].然后将初始权值从大到小进行排序 ...
- As 400错
8:25 Gradle sync started 8:25 Gradle sync failed: Unable to tunnel through proxy. Proxy returns &quo ...
- 《Kafka权威指南》读书笔记-操作系统调优篇
<Kafka权威指南>读书笔记-操作系统调优篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 大部分Linux发行版默认的内核调优参数配置已经能够满足大多数应用程序的运 ...
- nginx的下载、编译安装和启动
一.nginx简介 nginx(“engine x”)是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器.nginx是由Igor Sysoev为俄罗斯访问量第二的R ...
- async+await处理异步问题
在编写网页的时候我们常常会遇到异步问题,async+await是es6提出的解决异步的方法,下面我们来看看这个方法怎么实现解决异步的, 大家都知道,setTimeout是一个定时器.他是一个异步执行的 ...
- 异常来自 HRESULT:0x80070057 (E_INVALIDARG)(转)
莫名其妙的编译总会报错 异常来自 HRESULT:0x80070057 (E_INVALIDARG) 未能加载程序集....... 几次删除引用然后重新引用程序集还是报错 奔溃中.... 网上搜索还真 ...
- Socket远程调试日志之 SocketLog的简单实用
github地址:https://github.com/luofei614/SocketLog 更多信息看这里:https://www.bbsmax.com/A/8Bz8L9Nyzx/ tp5配置co ...