【问题描述】

Mark Douglas是一名优秀的锻造师。与他优秀的锻造水平不相符,他非常穷,以至于很多好刀都因为缺少素材缺少资金无法打造。

Mark把他有能力锻造的所有n种刀建成了一棵锻造树,除了第1种刀可以直接打造以外,其他的刀都只能从某一种刀加工而来。具体而言,第i种刀只能从第fai种刀加工而来,花费的费用为wi,但是第fai种刀不能由第i种刀逆加工得到。Mark定义一种刀的价值为利用他现有的刀进行打造的花费。他虽然穷,但是眼光很高,价值低于一定值的刀他都看不上。现在有q次询问,每次询问当Mark手里有第u种刀且他能看上的最小价值为k时,他能看上的所有刀的价值和是多少。

【输入格式】

输入文件名为forging.in

第一行为一个正整数n

接下来n-1行,每行两个正整数fai wi

下一行一个正整数q

接下来q行,每行两个正整数u k

【输出格式】

输出文件名为forging.out

输出q行,每行表示一组询问的答案。

输入:

3

1 2

1 3

2

1 3

1 2

输出:

3

5

【数据范围】

对于1~4号测试点(20%):1<=n,q<=1000。

对于1~8号测试点(40%)1<=n,q<=100000,1<=k<=50。

对于9~10号测试点(10%):树的形态为一条链。

对于9~14号测试点(30%):除1号点外其余所有点的度数不超过2。

对于所有测试点(100%)1<=n,q<=100000,1<=k<=1e9,1<=wi<=1000。

首先这道题,我们可以把它看作主席树裸题,也可以看成线段树合并模板;

然而这里所说的是用分块维护树剖;

一开始我们将这个树进行树链剖分,注意,我们并不用线段树来维护,所以只要把树剖的预处理部分写出来就好了;

我们知道树剖的性质(dfs序当然也可以):一个以根节点和它的所有子节点所形成的集合是在一段连续的区间;

那么对于每次询问,在每块里二分位置,把每块里大与这个位置的数都累加到答案中;

注意一个细节:当二分的答案是这个区间的最右端时,一定要特判这个点是否满足条件;

时间复杂度时一个O(nlogn+q*sqrt(n)*logn);

可过,不用离线处理,不用离散化,再大的数据范围也可以这么做;

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int head[200010],cnt;
class littlestar{
public:
int to;
int nxt;
int w;
void add(int u,int v,int gg){
to=v;
nxt=head[u];
head[u]=cnt;
w=gg;
}
}star[2000010];
int n;
long long val[100010];
int f[100010],top[100010],seg[100010],dep[100010],size[100010],rev[100010],son[100010];
long long b[100010];
void dfs1(int u,int fa)
{
dep[u]=dep[fa]+1;
f[u]=fa;
size[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==fa) continue;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]){
son[u]=v;
}
}
}
void dfs2(int u,int fa)
{
if(son[u]){
seg[son[u]]=++seg[0];
rev[seg[0]]=son[u];
top[son[u]]=top[u];
dfs2(son[u],u);
}
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==fa) continue;
if(!top[v]){
seg[v]=++seg[0];
rev[seg[0]]=v;
top[v]=v;
dfs2(v,u);
}
}
}
void build()
{
seg[0]=seg[1]=rev[1]=top[1]=1;
dfs1(1,0);
dfs2(1,0);
inc(i,1,n){
b[i]=val[rev[i]];
}
}
void dfs(int u,int fa)
{
for(register int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==fa) continue;
val[v]=val[u]+star[i].w;
dfs(v,u);
}
}
int num;
int belong[100010],l[100010],r[100010],block;
long long gg[100010];
long long sum[100010];
void build2()
{
block=sqrt(n);
num=n/block;
if(n%block) ++num;
inc(i,1,n){
gg[i]=b[i];
belong[i]=((i-1)/block)+1;
}
inc(i,1,num){
l[i]=block*(i-1)+1;
r[i]=block*i;
}
r[num]=n;
inc(i,1,num){
sort(gg+l[i],gg+1+r[i]);
}
inc(i,1,n) sum[i]=sum[i-1]+gg[i];
}
long long ans;
inline void query(register int x,register int y,long long goal)
{
if(belong[x]==belong[y]){
for(int j=x;j<=y;j++){
if(b[j]-b[x]>=goal) ans+=(b[j]-b[x]);
}
return;
}
for(register int i=x;i<=r[belong[x]];i++){
if(b[i]-b[x]>=goal) ans+=(b[i]-b[x]);
}
for(register int i=l[belong[y]];i<=y;i++){
if(b[i]-b[x]>=goal) ans+=(b[i]-b[x]);
}
for(register int i=belong[x]+1;i<=belong[y]-1;i++){
register int L=l[i],R=r[i],mid;
while(L<R){
mid=(L+R)/2;
if(gg[mid]-b[x]>=goal){
R=mid;
}
else{
L=mid+1;
}
}
if(L==r[i]){
if(gg[L]-b[x]>=goal){
ans+=gg[L]-b[x];
}
continue;
}
ans+=(sum[r[i]]-sum[L-1]-b[x]*(r[i]-L+1));
}
}
template<class nT>
inline void read(nT& x)
{
char c;
while(c=getchar(),!isdigit(c));
x=c^48;
while(c=getchar(),isdigit(c)) x=x*10+c-48;
}
int main()
{
read(n);
inc(i,2,n){
int u,w; scanf("%d%d",&u,&w);
star[++cnt].add(u,i,w);
}
dfs(1,0);
build();
build2();
int q;read(q);
inc(i,1,q){
ans=0;
long long x,goal;
read(x); read(goal);
query(seg[x],seg[x]+size[x]-1,goal);
printf("%lld\n",ans);
}
}
/*
3
1 2
1 3
2
1 3
1 2 6
1 2
1 2
3 3
3 4
2 5
2
3 2 7
3 1
1 2
3 1
4 2
4 1
4 2
5 */

NOIP模拟赛 打铁的匠 题解的更多相关文章

  1. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  2. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

  3. CH Round #48 - Streaming #3 (NOIP模拟赛Day1)

    A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...

  4. CH Round #54 - Streaming #5 (NOIP模拟赛Day1)

    A.珠 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/珠 题解:sb题, ...

  5. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  6. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  7. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  8. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  9. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

随机推荐

  1. kubernetes 之部署metrics-server v0.3.1

    Metrics-server简介 Metrics-server是用来替换heapster获取集群上资源指标数据的,heapster从1.11开始逐渐被废弃了. 在使用heapster时,获取资源指标是 ...

  2. oracle函数mysql替代方案

    =====1.日期相关===//获取当前日期在本周的周一select subdate(now(),date_format(now(),'%w')-1);//获取当前日期在本周的周日 select su ...

  3. 说说如何使用unity Vs来进行断点调试

    转载自:http://dong2008hong.blog.163.com/blog/static/4696882720140293549365/ 大家可以从这下载最新版的unity vs. Unity ...

  4. python struct的使用例子

    import struct i = 1024 # s0为一个字符串,长度为4,即占四个字节,这样方便传输与保存二进制数据. s0 = struct.pack(">I", i) ...

  5. Nginx-HTTP之ngx_http_top_header_filter

    1. ngx_http_top_header_filter 该链表主要是用于构造响应消息的消息报头. ngx_http_top_header_filter 单链表有如下模块插入了操作: ngx_htt ...

  6. Java-NIO 之 Selector 与 Pipe

    关于阻塞与非阻塞:https://www.cnblogs.com/jhxxb/p/11272727.html 一.传统的 IO 流都是阻塞式的 当一个线程调用 read() 或 write() 时,该 ...

  7. docker mysql容器的安装使用

    docker拉取镜像的命令为 docker pull image[:TAG] 如果我们想安装的mysql版本不是最新的版本,则需要填充TAG,如果不带上TAG,则默认安装的为最新版本,虽然可以通过do ...

  8. Web服务器磁盘满深入解析及解决

    ########################################################## 硬盘显示被写满但是用du -sh /*查看时占用硬盘空间之和还远#小于硬盘大小问的 ...

  9. 【log4j】log4j.properties 文件示例

    # 下面的文件内容是写程序长期要用的,放在这里留个底#Output information(higher than INFO) to stdout and file.info/debug/error ...

  10. ubuntu更换源的方法

    1.查看ubuntu版本的方法: 使用命令 sudo lsb_release -a 输出如下: root@localhost:/etc/apt# sudo lsb_release -aNo LSB m ...