NOIP模拟赛 打铁的匠 题解
【问题描述】
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模拟赛 打铁的匠 题解的更多相关文章
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
- CH Round #48 - Streaming #3 (NOIP模拟赛Day1)
A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...
- 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题, ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
随机推荐
- python 字符串模板
from string import Template print(type(Template)) mystr = Template("hi,$name 你是$baby") pri ...
- Django-安装/分组命名/路由分发
一.安装Django 命令行窗口: pycharm安装: 二.创建Django项目 命令行窗口创建项目: 访问地址: 表示访问成功 注意如果我们在命令行窗口创建的应用需要我们手动的在django的se ...
- CSS高级学习-1
优先级 权值 标签权值为1,类权值为10,ID权值最高为100. p{color:red;} /*权值为1*/ p span{color:green;} /*权值为1+1=2*/ .warning{c ...
- Cannot find ./catalina.sh The file is absent or does not have execute permission This file is nee Linux上tomcat无法正常启动
上传了个tomcat7的压缩包上linux服务器,解压后,想直接启动,发现报错: Cannot find ./catalina.sh The file is absent or does not ha ...
- 03 HTTP协议与HTTPS协议
一.HTTP协议 1.官方概念: HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文 ...
- 获取当前页面的webview ID
代码: A页面 <script type="text/javascript"> var ws = null; mui.plusReady(function(){ ws ...
- 终端和vim中文编码问题
一. 终端中文显示乱码 有网友说修改 /var/lib/locales/supported.d/locale 和 /etc/default/locale 就可以了但是如果多人共用一台机器没有root权 ...
- 【软件工程】Beta冲刺(5/5)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...
- postgresql获取表最后更新时间(通过触发器将时间写入另外一张表)
通过触发器方式获取表最后更新时间,并将时间信息写入到另外一张表 一.创建测试表和表记录更新时间表 CREATE TABLE weather( city varchar(80), temp_lo int ...
- 工具类注入需要的service
/** * 从redis获取信息 * @author yy * */ @Component//关键一:添加此注解才能被spring扫描到 public class CacheUtil { privat ...