CodeForces - 396C On Changing Tree(树状数组)
题目大意
给定一棵以1为根的树,初始时所有点为0
给出树的方式是从节点2开始给出每一个点的父亲
然后是 $m$ 次操作,分为两种
$1 v,k,x$ 表示在以v为根的子树中的每一个点上添加 $x-i*k$( $i$ 表示节点与 $v$ 的距离)(包括点 $v$ )
$2 v$ 查询节点 $v$ 的值
输出每一个2操作的答案模 $1e9+7$ 的值
题解
话说真没想到这题竟然这么简单……死活都想不出来……
先dfs预处理出每一个节点的dfs序,以及子树代表的区间$ls$和$rs$,以及每一个点的深度$dep$
假设先$add(ls[v],x+dep[v]*k),add(rs[v]+1,-x-dep[v]*k)$,然后用树状数组维护前缀和,树状数组设为$c1$
可以发现,$v$这个点多加去了$dep[v]*k$,要减掉。同理可得,$v$的所有子树都要减掉$dep[j]*k$($j$为$v$的子节点)
可以证明以上这么乱搞之后每一个点的值都加上了正确的数
乱证:$j$节点经过这一操作后加上了$dep[v]*k-dep[j]*k=k*(dep[j]-dep[v])=k*dis[v,j]$
然后证明每一个节点都加上了正确的数值
那么只要再开一个树状数组维护前缀$k$就可以了
查询的答案就是$sum(ls[v],c1)-sum(ls[v],c2)*dep[v]$
//minamoto
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(ll x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=,mod=1e9+;
int ver[N],head[N],Next[N],dep[N];
int ls[N],rs[N];
ll c[][N];
int n,tot,q,cnt;
inline void add(int x,ll val,int k){
for(int i=x;i<=n;i+=i&(-i))
(c[k][i]+=val)%=mod;
}
inline ll sum(int x){
ll a=,b=;
for(int i=ls[x];i;i-=i&(-i)){
a+=c[][i],b+=c[][i];
}
return ((a-b*dep[x])%mod+mod)%mod;
}
void dfs(int u,int fa){
ls[u]=++cnt;
dep[u]=dep[fa]+;
for(int i=head[u];i;i=Next[i]) dfs(ver[i],u);
rs[u]=cnt;
}
int main(){
//freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i){
int fa=read();
ver[++tot]=i,Next[tot]=head[fa],head[fa]=tot;
}
dfs(,);
q=read();
while(q--){
int opt=read(),v=read();
if(opt&) print(sum(v));
else{
ll x=read(),k=read();
add(ls[v],x+dep[v]*k,);
add(rs[v]+,-x-dep[v]*k,);
add(ls[v],k,);
add(rs[v]+,-k,);
}
}
Ot();
return ;
}
CodeForces - 396C On Changing Tree(树状数组)的更多相关文章
- CodeForces 396C On Changing Tree
On Changing Tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...
- codeforces#1167F. Scalar Queries(树状数组+求贡献)
题目链接: https://codeforces.com/contest/1167/problem/F 题意: 给出长度为$n$的数组,初始每个元素为$a_i$ 定义:$f(l, r)$为,重排$l$ ...
- HDU3333 Turing Tree 树状数组+离线处理
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- POJ 3321 Apple Tree(树状数组)
Apple Tree Time Limit: 2000MS Memory Lim ...
- HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
- POJ--3321 Apple Tree(树状数组+dfs(序列))
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 22613 Accepted: 6875 Descripti ...
- CodeForces 828E DNA Evolution(树状数组)题解
题意:给你一个串k,进行两个操作: “1 a b”:把a位置的字母换成b “2 l r s”:求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s形成一个串ss,然后匹配ss和指定区间的 ...
- Codeforces 909C Python Indentation:树状数组优化dp
题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...
- gym 100589A queries on the Tree 树状数组 + 分块
题目传送门 题目大意: 给定一颗根节点为1的树,有两种操作,第一种操作是将与根节点距离为L的节点权值全部加上val,第二个操作是查询以x为根节点的子树的权重. 思路: 思考后发现,以dfs序建立树状数 ...
随机推荐
- Android开发实战之简单音乐播放器
最近开始学习音频相关.所以,很想自己做一个音乐播放器,于是,花了一天学习,将播放器的基本功能实现了出来.我觉得学习知识点还是蛮多的,所以写篇博客总结一下关于一个音乐播放器实现的逻辑.希望这篇博文对你的 ...
- 【hdu6148】Valley Numer【数位dp模板题】
题意 对于每组数据给出一个整数n(length(n)<=100),找出不大于n的数字中有多少是Valley Numer.对于Valley的定义是它每一位的数字要么是递增,要么是递减,要么是先递减 ...
- Codeforces 721E DP
大概思路及题意看这篇博客吧 我的理解:设f[i]表示处理到第i个区间,能唱的最多的歌,g[i]是保证f[i]最大时最靠左的点.那么f[i] = max(f[j] + (r[i] - max(l[i], ...
- 规范抢先看!微信小程序的官方设计指南和建议
基于微信小程序轻快的特点,我们(微信官方)拟定了小程序界面设计指南和建议. 设计指南建立在充分尊重用户知情权与操作权的基础之上.旨在微信生态体系内,建立友好.高效.一致的用户体验,同时最大程度适应和支 ...
- DBArtist之Oracle入门第2步: 了解Oracle的Database Control
之前安装好数据库后,会有下面这个弹窗,然后根据Database Control URL地址进入瞧一瞧,看一看! 根据地址进入以后,是一个登录界面,用system账户登录,密码就是安装Oracle的时候 ...
- VS2017在Release下编译错误C1001
在使用VS2017编译C程序时,Debug模式下编译链接执行都没有问题,但是一转到Release模式下就出现下列编译链接错误(IDE:VS2017 /VC++/MFC程序,目标平台x86+Win32位 ...
- #error用法
#error命令是C/C++语言的预处理命令之一,当预处理器预处理到#error命令时将停止编译并输出用户自定义的错误消息. 语法: #error [用户自定义的错误消息] 注:上述语法成份中的方括号 ...
- Mysql Join语法以及性能优化
引言 内外联结的区别是内联结将去除所有不符合条件的记录,而外联结则保留其中部分.外左联结与外右联结的区别在于如果用A左联结B则A中所有记录都会保留在结果中,此时B中只有符合联结条件的记录,而右联结相反 ...
- mac iterm2
配置的效果图 : 先讲 iterm2 的配色,再讲 显示分支以及高亮. 一. 配色 打开iterm的官方主题配置站 github.com/mbadolato/iTerm2-Color-Schemes, ...
- springboot启动正常,访问restController报404
原因:spring boot只会扫描启动类当前包和以下的包 比如以下: 主类:Application放在包com.springboot.main controller类放在包com.springboo ...