Description

Crystal家有一棵树。树上有\(n\)个节点,编号由\(1\)到\(n\)(\(1\)号点是这棵树的根),两点之间距离为1当且仅当它们直接相连。每个点都有各自的权值,第\(i\)号节点的权值为\(value_i\)。Crystal现在指着编号为\(x\)的点问,在以点\(x\)为根的子树中,与点\(x\)距离大于等于\(k\)的所有点的点权和是多少。

Input Format

第\(1\)行两个整数\(n,Q\),分别表示树上点的个数和Crystal有\(Q\)个问题。

第\(2\)行,\(n\)个整数,分别表示\(1\)至\(n\)号点的点权。

接下来的\(n - 1\)行,每行两个整数\(u,v\),表示编号为\(u\)的点与编号为\(v\)的点直接相连。

接下来\(Q\)行,每行两个整数\(x,k\),表示询问在以点\(x\)为根的子树中,与点\(x\)距离大于等于为\(k\)的所有点的点权和是多少。

Output Format

\(Q\)行,每行一个整数,表示对第\(i\)个询问的回答。

Sample Input

5 3

1 1 1 1 1

1 2

1 3

3 4

4 5

1 3

1 2

1 1

Sample Output

1

2

4

Hints

对于\(30\%\)的数据,保证\(n \le 1000, k < 1, Q \le 1000\)。

对于\(60\%\)的数据,保证\(n \le 1000, k < 1000, Q \le 1000\)

对于\(80\%\)的数据,保证\(n \le 1000, k < 1000, Q \le 1000000\);

对于最后\(20\%\)的数据,保证\(n \le 50000, k < 100, Q \le 1000000\);

对于\(100\%\)的数据,保证所有输入数据均为非负整数,且在\(int\)范围内。

这题\(O(NK)\)的做法不难想(用总的减去小于\(K\)的),现在假设\(N,K\)同级怎么做。

首先考虑离线做法,我们可以考虑按照询问最深的深度从小到大一层层加点,答案还是用总的减去小于\(K\)的。

再考虑在线所做法,我们可以先处理出dfs序和子树和,然后对于树的每层开一个vector,vector中记录该层点的编号,按dfs序排序。对于每个询问\(x,k\),我们只需要跳到\(dep[x]+k\)层的vector中,找到在\(x\)子树中的点,且一定是段连续区间,二分即可。现在只需要对该区间求子树和的和即可。

代码是\(O(NK)\)的

    #include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std; typedef long long ll;
#define maxn (50010)
int cnt = 1,side[maxn],toit[maxn*2],next[maxn*2],val[maxn],N,Q,mxk;
int tx[maxn*20],tk[maxn*20],num[20],len; ll sum[maxn]; vector <ll> res[maxn]; inline int read()
{
char ch; int f = 1,ret = 0;
do ch = getchar(); while (!(ch >= '0'&&ch <= '9')&&ch != '-');
if (ch == '-') f = -1,ch = getchar();
do ret = ret*10+ch-'0',ch = getchar(); while (ch >= '0'&&ch <= '9');
return ret*f;
} inline void add(int a,int b) { next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; }
inline void ins(int a,int b) { add(a,b); add(b,a); } inline void dfs(int now,int fa)
{
for (int i = 0;i <= mxk;++i) res[now].push_back(val[now]);
sum[now] = val[now];
for (int i = side[now];i;i = next[i])
{
if (toit[i] == fa) continue;
dfs(toit[i],now);
sum[now] += sum[toit[i]];
for (int j = 0;j < mxk;++j)
res[now][j+1] += res[toit[i]][j];
}
} inline void print(ll a)
{
do num[++len] = a%10,a /= 10; while (a);
while (len) putchar('0'+num[len--]);
puts("");
} int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
N = read(); Q = read();
for (int i = 1;i <= N;++i) val[i] = read();
for (int i = 1;i < N;++i) ins(read(),read());
for (int i = 1;i <= Q;++i) tx[i] = read(),tk[i] = read(),mxk = max(mxk,tk[i]);
dfs(1,0);
// print(123456LL);
// print(0LL);
// print(12LL);
for (int i = 1;i <= Q;++i)
{
if (!tk[i]) //cout << sum[tx[i]] << endl;
print(sum[tx[i]]);
else //cout << sum[tx[i]]-res[tx[i]][tk[i]-1] << endl;
print(sum[tx[i]]-res[tx[i]][tk[i]-1]);
}
//fclose(stdin); fclose(stdout);
return 0;
}

sjtu1591 Count On Tree的更多相关文章

  1. leetcode面试准备:Count Complete Tree Nodes

    1 题目 Given a complete binary tree, count the number of nodes. In a complete binary tree every level, ...

  2. leetcode 958. Check Completeness of a Binary Tree 判断是否是完全二叉树 、222. Count Complete Tree Nodes

    完全二叉树的定义:若设二叉树的深度为h,除第 h 层外,其它各层 (1-h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树. 解题思路:将树按照层进行遍历,如果 ...

  3. 完全二叉树的节点个数 Count Complete Tree Nodes

    2018-09-25 16:36:25 问题描述: 问题求解: 单纯遍历了一遍,emmm,果然TLE. 解题思路就是比较左边树高度和右边树高度,如果相等,那么就是一个满二叉树,返回1 << ...

  4. 【LeetCode】222. Count Complete Tree Nodes 解题报告(Python)

    [LeetCode]222. Count Complete Tree Nodes 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个 ...

  5. 【刷题-LeetCode】222. Count Complete Tree Nodes

    Count Complete Tree Nodes Given a complete binary tree, count the number of nodes. Note: Definition ...

  6. [LeetCode] Count Complete Tree Nodes 求完全二叉树的节点个数

    Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...

  7. Count Complete Tree Nodes

    Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...

  8. Java for LeetCode 222 Count Complete Tree Nodes

    Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...

  9. leetcode_222 Count Complete Tree Nodes

    题目: Given a complete binary tree, count the number of nodes. Definition of a complete binary tree fr ...

随机推荐

  1. hackerrank Day 10: Binary Numbers

    Task Given a base-10 integer, n, convert it to binary (base-2). Then find and print the base-10 inte ...

  2. 【转】傅盛:怎样做一个创业公司CEO?

    摘要 : 傅盛High聊会,泉灵姐姐给的命题作文.怎样做一个创业公司CEO,核心还是思维模式. 这次傅盛High聊会,泉灵姐姐给我的命题作文.创业要如何开始,本质还是思维模式.首先学会把一个开放式问题 ...

  3. 用js操作表格

    效果图: 任务: 1. 鼠标移到不同行上时背景色改为色值为 #f2f2f2,移开鼠标时则恢复为原背景色 #fff var tr=document.getElementsByTagName(" ...

  4. Sqlserver基于流程控制

    流程控制语句只能在单个批处理段,用户自定义函数和存储过程中使用不能夸多个批处理或者用户自定义函数或者存储过程 批处理:一个或者多个语句组成的一个批处理,是因为所有语句一次性地被提交到一个sql实例,如 ...

  5. JD(转载)

    时间:2012-9-11 地点:川大 我只能说第一家公司,不是一般的火爆.不得不吐槽一下: 京东宣讲完全没有计划,只看到个下午两点半宣讲,结果跑过去,下午两点是宣讲管培的.在川大外的德克士呆了一下午. ...

  6. 命令行创建AVD

    1.命令行创建AVD android create avd -n myAvd -t 8 -b armeabi-v7a -p d:\scard.img -s HVGA 2.删除AVD android d ...

  7. JQuery 之 Ajax 异步和同步浅谈

    Ajax 同步和异步的区别 同步是当 JS 代码加载到当前 Ajax 的时候会把页面里所有的代码停止加载,页面出现假死状态:当这个 Ajax 执行完毕后才会继续运行其他代码此时页面假死状态才会解除.反 ...

  8. Java获取线程的对象和名称

    /*获取线程对象以及名称(很有意义的) 原来线程都有自己默认的名称Thread-编号  该编号从0开始 Thread 父类的方法static  Thread currentThread() :获取当前 ...

  9. Installation Phases and In-Script Execution for Custom Actions in Windows Installer

    用 InstallShield 依照 Custom Action Wizard 创建 Custom Action 时,会遇到下面的几个选项: In-Script Execution Install U ...

  10. 清橙 A1120 拦截导弹 -- 动态规划(最长上升子序列)

    题目地址:http://oj.tsinsen.com/A1120 问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但 ...