题目描述

方方方种下了三棵树,两年后,第二棵树长出了n个节点,其中1号节点是根节点。

给定一个n个点的树

支持两种操作

方方方进行m次操作,每个操作为:

(1)给出两个数i,x,将第i个节点的子树中,与i距离为斐波那契数的节点权值+x(包括i本身)。

(2)给出一个数i,求出第i个节点的子树中,与i距离为斐波那契数的节点的权值和(包括i本身)。

题解

斐波那契数列

首先这个会被操作的只有大概25层的节点。

这样深度相同的区间在bfs序上是连续的区间,那么只要求出这样的左右端点是哪些,后面的就可以建个线段树|树状数组维护

原来我觉得这样的区间很难求。其实只要类似倍增的做法表示i的次祖先。就可以直接求了。

bfs序上的区间修改/查询 还可以用bit

这类的玩意http://www.cnblogs.com/zzqsblog/p/5692627.html

#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
bool f=true;Ri x=;char ch;while(!isdigit(ch=gc))if(ch=='-')f=false;while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=gc;}return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
struct edge{
int to,next;
}e[];
int last[],dep[],val[],f[][],cnt,n,m;
ll sum;
il void link(int a,int b){
e[++cnt]=(edge){b,last[a]};last[a]=cnt;
e[++cnt]=(edge){a,last[b]};last[b]=cnt;
}
int lf[][],rf[][],bfn[],_bfn;
// i的fib_i层的左&右
void dfs(int x,int fa=){
dep[x]=dep[fa]+;
f[x][]=f[x][]=fa;
for(int i=;i<=;i++)f[x][i]=f[f[x][i-]][i-];
for(int i=last[x];i;i=e[i].next){
if(e[i].to!=fa){
dfs(e[i].to,x);
}
}
}
bool vis[];
void bfs(int s){
memset(vis,,sizeof(vis));
queue<int>q;
q.push(s);vis[s]=true;bfn[]=++_bfn;
while(!q.empty()){
int c=q.front();q.pop();
for(int i=last[c];i;i=e[i].next){
if(!vis[e[i].to]){
q.push(e[i].to);
vis[e[i].to]=true;
bfn[e[i].to]=++_bfn;
}
}
}
}
void yuchuli(){
dfs();
bfs();
memset(lf,,sizeof(lf));
for(int i=;i<=n;i++){
for(int j=;j<=;j++){
int anc=f[i][j];
if(!anc)break;
gmin(lf[anc][j],bfn[i]);
gmax(rf[anc][j],bfn[i]);
}
}
for(int i=;i<=n;i++)
lf[i][]=rf[i][]=bfn[i];
}
namespace bit{
ll a1[],a2[];
ll qzh(int r){
ll s1=,s2=;
for(int i=r;i>=;i-=i&-i) s1+=a1[i], s2+=a2[i];
return (r+)*s1-s2;
}
ll sum(int l,int r){
return qzh(r)-qzh(l-);
}
void edt(ll a,ll s1){
ll s2=a*s1;
for(;a<=n;a+=a&-a) a1[a]+=s1, a2[a]+=s2;
}
void edt(int l,int r,ll a) {edt(l,a); edt(r+,-a);}
}
void _chg(int x,int y){
for(int i=;i<=;i++){
if(!rf[x][i])break;
bit::edt(lf[x][i],rf[x][i],y);
}
}
ll _qry(int x){
sum=;
for(int i=;i<=;i++){
if(!rf[x][i])break;
sum=sum+bit::sum(lf[x][i],rf[x][i]);
}
return sum;
}
int main(){
//FO(tree2);
n=gi;m=gi;
for(int i=;i<n;i++){
int a,b;
a=gi;b=gi;
link(a,b);
}
yuchuli();
while(m--){
int op,x,y;
op=gi;
if(op==){
x=gi;
printf("%I64d\n",_qry(x));
}
if(op==){
x=gi;y=gi;
_chg(x,y);
//puts("");
}
}
}

OrzFAng系列–树 解题报告的更多相关文章

  1. 【九度OJ】题目1172:哈夫曼树 解题报告

    [九度OJ]题目1172:哈夫曼树 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1172 题目描述: 哈夫曼树,第一行输入一个数n, ...

  2. poj2528线段树解题报告,离散化+线段树

    题目网址:http://poj.org/problem?id=2528 题意: n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=1 ...

  3. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  4. 「SHOI2014」三叉神经树 解题报告

    「SHOI2014」三叉神经树 膜拜神仙思路 我们想做一个类似于动态dp的东西,首先得确保我们的运算有一个交换律,这样我们可以把一长串的运算转换成一块一块的放到矩阵上之类的东西,然后拿数据结构维护. ...

  5. 洛谷 P3924 康娜的线段树 解题报告

    P3924 康娜的线段树 题目描述 小林是个程序媛,不可避免地康娜对这种人类的"魔法"产生了浓厚的兴趣,于是小林开始教她\(OI\). 今天康娜学习了一种叫做线段树的神奇魔法,这种 ...

  6. [BZOJ1984]月下“毛景树”解题报告|树链剖分

    Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里.爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树” ...

  7. 洛谷1087 FBI树 解题报告

    洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...

  8. 「ZJOI2019」线段树 解题报告

    「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...

  9. 【九度OJ】题目1176:树查找 解题报告

    [九度OJ]题目1176:树查找 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1176 题目描述: 有一棵树,输出某一深度的所有节点 ...

随机推荐

  1. linux 常用命令及技巧

    linux 常用命令及技巧 linux 常用命令及技巧:linux 常用命令总结: 一. 通用命令: 1. date :print or set the system date and time 2. ...

  2. php下intval()和(int)转换有哪些区别

    想知道使用intval()和(int)转换有什么区别? 或者说两者有什么不同,包括功能.定义方面的.或者和使用频率.效率等. 复制代码代码如下: <?php  echo "<br ...

  3. 关于Raw,Assets的使用

    Raw,Assets下文件区别: 相同点:两个目录下的文件在打包后都会原封不动的保存到apk中,不会被编译成二进制. 不同点:Raw下文件不能使用目录结构, 有些格式的会被压缩,能够通过R.raw方便 ...

  4. delphi中表示跳出的有break,continue, exit,abort, halt, runerror

      1.break 强制退出循环(只能放在循环中),用于从For语句,while语句或repeat语句中强制退出. 2.continue 用于从For语句,while语句或repeat语句强行结束本次 ...

  5. 【转】Linux Soclet编程

    原文地址:http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编 ...

  6. 第九章 管理类型(In .net4.5) 之 继承机制

    1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...

  7. 刀哥多线程现操作gcd-10-delay

    延迟操作 // MARK: - 延迟执行 - (void)delay { /** 从现在开始,经过多少纳秒,由"队列"调度异步执行 block 中的代码 参数 1. when 从现 ...

  8. 【转】SQLite提示database disk image is malformed的解决方法

    SQLite有一个很严重的缺点就是不提供Repair命令. 导致死亡提示database disk image is malformed 它的产生有很多种可能,比如,磁盘空间不足,还有就是写入数据过程 ...

  9. hdu 1316 How Many Fibs?

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1316 How Many Fibs? Description Recall the definition ...

  10. windows phone版的一个儿教app

    昨天下午看见一个园友写的一篇关于儿教的api,看了也就两三个接口,所以数据处理应该不会太复杂,主要是界面的效果,要求可能比较高.于是我就重新自己写了一个app,实现很简单,花的时间比较多的地方应该是在 ...