题目链接:

F - Change

FZU - 2277

题目大意:

题意: 给定一棵根为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序+线段树)的更多相关文章

  1. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  2. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

  3. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  4. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

  5. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  6. 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 ...

  7. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  8. 【cf343】D. Water Tree(dfs序+线段树)

    传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...

  9. BZOJ 3252题解(贪心+dfs序+线段树)

    题面 传送门 分析 此题做法很多,树形DP,DFS序+线段树,树链剖分都可以做 这里给出DFS序+线段树的代码 我们用线段树维护到根节点路径上节点权值之和的最大值,以及取到最大值的节点编号x 每次从根 ...

随机推荐

  1. Vue的简单入门

    Vue的简单入门 一.什么是Vue? vue.js也一个渐进式JavaScript框架,可以独立完成前后端分离式web项目 渐进式:vue可以从小到控制页面中的一个变量后到页面中一块内容再到整个页面, ...

  2. RabbitMQ 消费者的消息确认机制

    消息确认的几点说明: 1. Basic.Ack 发回给 RabbitMQ 以告知,可以将相应 message 从 RabbitMQ 的消息缓存中移除.2. Basic.Ack 未被 consumer ...

  3. MYSQL Innodb逻辑存储结构

    转载于网络 这几天在读<MySQL技术内幕 InnoDB存储引擎>,对 Innodb逻辑存储结构有了些了解,顺便也记录一下: 从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放 ...

  4. 位掩码(BitMask)的介绍与使用

    一.前言 位运算在我们实际开发中用得很少,主要原因还是它对于我们而言不好读.不好懂.也不好计算,如果不经常实践,很容易就生疏了.但实际上,位运算是一种很好的运算思想,它的优点自然是计算快,代码更少. ...

  5. SVN提交前准备

    操作步骤1: 操作步骤2: 操作步骤3: 操作步骤4: 操作步骤5: 操作步骤6:查看 操作步骤7:ignore 操作步骤8:直接提交项目

  6. ADB interface驱动

    原文地址:https://blog.csdn.net/weixin_42108952/article/details/80153402

  7. python csv与字典操作

    # encoding: utf-8 import csv d1 = {'banana':3,'apple':4,'pear':1,'orange':2} d2 = {'banana':3,'orang ...

  8. 【MSSQL】How can i see what IP address made the request to SQL Server?

    How can i see what IP address made the request to SQL Server? #背景 前提:有一个服务定时读取某台服务器上的sql server 数据库, ...

  9. HDU - 3642 Get The Treasury(线段树求体积交)

    https://cn.vjudge.net/problem/HDU-3642 题意 求立方体相交至少3次的体积. 分析 三维的呢..首先解决至少覆盖三次的问题.则用三个标记,更新时的细节要注意. 注意 ...

  10. vue中slot插槽

    插槽就是vue实现的一套内容分发的API,将插槽元素作为承载分发内容的出口. 也就是说在组件模板中默认占用一个位置,当使用组件标签时候,组件标签的内容就会自动替换掉内容 slot中可以设置一些默认的内 ...