已知完全二叉树和每条边的权值,q次询问,每次给出sta起点和H。

w=(H-点到sta的权值),求w>0的所有w的加和。

这题用树上前缀和来写,e[i]记录子树上的点到点i的距离,sum[i][j]为e[i]的前缀和

这样每次找到满足大于h-len[i]的长度就行(二分查找)

void init(){
for(ll x=n;x>=;x--){
e[x].push_back();
ll lc=x<<;ll rc=x<<|;
if(lc<=n){
for(int i=;i<e[lc].size();i++){
e[x].push_back(e[lc][i]+len[lc-]);
}
}
if(rc<=n){
for(int i=;i<e[rc].size();i++){
e[x].push_back(e[rc][i]+len[rc-]);
}
}
sort(e[x].begin(),e[x].end());
sum[x].resize(e[x].size());
for(int i=;i<e[x].size();i++){
sum[x][i]=sum[x][i-]+e[x][i];
}
}
}
ll query(int x,ll h){
if(h<=)return ;
int index=upper_bound(e[x].begin(),e[x].end(),h)-e[x].begin();
return index*h-sum[x][index-];
}
int main()
{
// freopen("in.txt","r",stdin);
int m;
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
scanf("%lld",&len[i]);
}
init();
while(m--){
ll a;
ll h;
ll pre=;
scanf("%lld%lld",&a,&h);
ll ans=;
while(a&&h>){
ans+=h;
ll lc=a<<;
ll rc=a<<|;
if(lc!=pre&&lc<=n){
ans+=query(lc, h-len[lc-]);
}
// cout<<ans<<"\n";
if(rc!=pre&&rc<=n){
ans+=query(rc, h-len[rc-]);
}
//cout<<ans<<"\n";
h-=len[a-];
pre=a;
a/=;
}
printf("%lld\n",ans);
}
}

最新文章

  1. BFC布局
  2. 解决Visual Studio 2010闪退问题
  3. LApacheMP基础环境搭建
  4. 1029c语言文法2理解
  5. HDU 2516 取石子游戏(斐波那契博弈)
  6. Webservice初接触
  7. PL/pgSQL学习笔记之四
  8. RCP学习笔记
  9. Vss服务端用户存在,但客户端登陆不进去
  10. Objective-C中的block块语法
  11. PHPStorm 最新版 去掉参数提示 parameter name hints
  12. JAVA_SE基础——35.static修饰成员函数
  13. bootstrap 菜单之手风琴效果
  14. 利用iframe实现无刷新提交
  15. Linux服务器调教日常
  16. Topographic ICA as a Model of Natural Image Statistics(作为自然图像统计模型的拓扑独立成分分析)
  17. dfs——皇后问题(回溯)
  18. asyncsocket的用法
  19. 《剑指offer》第一题(重载赋值运算符)
  20. msys2 启用windows PATH环境变量

热门文章

  1. Java小白入门:聊聊Java这门编程语言
  2. .net core 认证与授权(三)
  3. Serverless 的运行原理与组件架构
  4. 场景6:具有OpenvSwitch的提供商网络
  5. Java入门基础(变量、操作符与表达式)
  6. java10幸运抽奖
  7. SpringBoot使用ELK日志收集ELASTIC (ELK) STACK
  8. sqlserver partitition and partition table --- partition show
  9. 一起了解 .Net Foundation 项目 No.1
  10. 源码编译安装MySQL5.7