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序建立树状数 ...
随机推荐
- bugfree调试
最近项目用到bugfree ,一直不能用,原来是session目录的文件权限有问题.
- ascii编码转utf8编码,适用于python2
def ascii2utf8(ascii): line = eval(("'" + ascii.strip() + "'")) return line
- Linux实战教学笔记46:NoSQL数据库之redis持久化存储 (二)
第3章 Redis数据类型详解 3.1 Redis键/值介绍 Redis key值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如"foo"的简单字符串到一个JPG ...
- Linux实战教学笔记27:Nginx详细讲解
前言:nginx的特点 本节主要对Nginx Web服务软件进行介绍,涉及Nginx的基础,特性,配置部署,优化,以及企业中的日常运维管理和应用.作为HTTP服务软件的后起之秀,Nginx与它的老大哥 ...
- HttpServletResponse返回页面弹窗
下载方法: @RequestMapping(value = "/download.htm") public void downLoadFile(String id,HttpServ ...
- SpringBoot整合SpringData和Mysql数据库
1.新建maven项目(具体的新建过程就不细说了) 2.添加maven依赖,也就是在pom.xml文件添加项目的依赖jar包: <project xmlns="http://maven ...
- 快速上手Runtime(二)之给分类添加属性
我们都知道,分类是不能直接添加属性的,那么我们有时候又需要实现这个功能,那么我们应该怎么办才能为分类添加上属性呢. Runtime给分类添加属性原理 给一个类声明属性,其实本质就是给这个类添加关联,并 ...
- PHP微信授权登录信息
文件1:index.php //换成自己的接口信息 $appid = 'XXXXX'; header('location:https://open.weixin.qq.com/connect/oaut ...
- SQL 数据库 学习 006 如何设置一个用户名和密码
我的电脑系统: Windows 10 64位 使用的SQL Server软件: SQL Server 2014 Express 先启动 SQL Server 2014 Management Studi ...
- IIS7日志中时间与系统时间不一致的原因
最近在分析web日志,发现IIS7日志中时间与系统时间不一致,即本该上班时间才产生的产并发访问日志,全部发生在凌晨至上班前. 本以为是系统时间设置错误,检查后一切正常.后查询资料,原来是这个原因: 日 ...