【问题描述】

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);

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

  1. #include <bits/stdc++.h>
  2. #pragma GCC optimize(2)
  3. #pragma GCC optimize(3)
  4. #pragma GCC optimize("Ofast")
  5. #pragma GCC optimize("inline")
  6. #pragma GCC optimize("-fgcse")
  7. #pragma GCC optimize("-fgcse-lm")
  8. #pragma GCC optimize("-fipa-sra")
  9. #pragma GCC optimize("-ftree-pre")
  10. #pragma GCC optimize("-ftree-vrp")
  11. #pragma GCC optimize("-fpeephole2")
  12. #pragma GCC optimize("-ffast-math")
  13. #pragma GCC optimize("-fsched-spec")
  14. #pragma GCC optimize("unroll-loops")
  15. #pragma GCC optimize("-falign-jumps")
  16. #pragma GCC optimize("-falign-loops")
  17. #pragma GCC optimize("-falign-labels")
  18. #pragma GCC optimize("-fdevirtualize")
  19. #pragma GCC optimize("-fcaller-saves")
  20. #pragma GCC optimize("-fcrossjumping")
  21. #pragma GCC optimize("-fthread-jumps")
  22. #pragma GCC optimize("-funroll-loops")
  23. #pragma GCC optimize("-fwhole-program")
  24. #pragma GCC optimize("-freorder-blocks")
  25. #pragma GCC optimize("-fschedule-insns")
  26. #pragma GCC optimize("inline-functions")
  27. #pragma GCC optimize("-ftree-tail-merge")
  28. #pragma GCC optimize("-fschedule-insns2")
  29. #pragma GCC optimize("-fstrict-aliasing")
  30. #pragma GCC optimize("-fstrict-overflow")
  31. #pragma GCC optimize("-falign-functions")
  32. #pragma GCC optimize("-fcse-skip-blocks")
  33. #pragma GCC optimize("-fcse-follow-jumps")
  34. #pragma GCC optimize("-fsched-interblock")
  35. #pragma GCC optimize("-fpartial-inlining")
  36. #pragma GCC optimize("no-stack-protector")
  37. #pragma GCC optimize("-freorder-functions")
  38. #pragma GCC optimize("-findirect-inlining")
  39. #pragma GCC optimize("-frerun-cse-after-loop")
  40. #pragma GCC optimize("inline-small-functions")
  41. #pragma GCC optimize("-finline-small-functions")
  42. #pragma GCC optimize("-ftree-switch-conversion")
  43. #pragma GCC optimize("-foptimize-sibling-calls")
  44. #pragma GCC optimize("-fexpensive-optimizations")
  45. #pragma GCC optimize("-funsafe-loop-optimizations")
  46. #pragma GCC optimize("inline-functions-called-once")
  47. #pragma GCC optimize("-fdelete-null-pointer-checks")
  48. #define inc(i,a,b) for(register int i=a;i<=b;i++)
  49. using namespace std;
  50. int head[200010],cnt;
  51. class littlestar{
  52. public:
  53. int to;
  54. int nxt;
  55. int w;
  56. void add(int u,int v,int gg){
  57. to=v;
  58. nxt=head[u];
  59. head[u]=cnt;
  60. w=gg;
  61. }
  62. }star[2000010];
  63. int n;
  64. long long val[100010];
  65. int f[100010],top[100010],seg[100010],dep[100010],size[100010],rev[100010],son[100010];
  66. long long b[100010];
  67. void dfs1(int u,int fa)
  68. {
  69. dep[u]=dep[fa]+1;
  70. f[u]=fa;
  71. size[u]=1;
  72. for(int i=head[u];i;i=star[i].nxt){
  73. int v=star[i].to;
  74. if(v==fa) continue;
  75. dfs1(v,u);
  76. size[u]+=size[v];
  77. if(size[v]>size[son[u]]){
  78. son[u]=v;
  79. }
  80. }
  81. }
  82. void dfs2(int u,int fa)
  83. {
  84. if(son[u]){
  85. seg[son[u]]=++seg[0];
  86. rev[seg[0]]=son[u];
  87. top[son[u]]=top[u];
  88. dfs2(son[u],u);
  89. }
  90. for(int i=head[u];i;i=star[i].nxt){
  91. int v=star[i].to;
  92. if(v==fa) continue;
  93. if(!top[v]){
  94. seg[v]=++seg[0];
  95. rev[seg[0]]=v;
  96. top[v]=v;
  97. dfs2(v,u);
  98. }
  99. }
  100. }
  101. void build()
  102. {
  103. seg[0]=seg[1]=rev[1]=top[1]=1;
  104. dfs1(1,0);
  105. dfs2(1,0);
  106. inc(i,1,n){
  107. b[i]=val[rev[i]];
  108. }
  109. }
  110. void dfs(int u,int fa)
  111. {
  112. for(register int i=head[u];i;i=star[i].nxt){
  113. int v=star[i].to;
  114. if(v==fa) continue;
  115. val[v]=val[u]+star[i].w;
  116. dfs(v,u);
  117. }
  118. }
  119. int num;
  120. int belong[100010],l[100010],r[100010],block;
  121. long long gg[100010];
  122. long long sum[100010];
  123. void build2()
  124. {
  125. block=sqrt(n);
  126. num=n/block;
  127. if(n%block) ++num;
  128. inc(i,1,n){
  129. gg[i]=b[i];
  130. belong[i]=((i-1)/block)+1;
  131. }
  132. inc(i,1,num){
  133. l[i]=block*(i-1)+1;
  134. r[i]=block*i;
  135. }
  136. r[num]=n;
  137. inc(i,1,num){
  138. sort(gg+l[i],gg+1+r[i]);
  139. }
  140. inc(i,1,n) sum[i]=sum[i-1]+gg[i];
  141. }
  142. long long ans;
  143. inline void query(register int x,register int y,long long goal)
  144. {
  145. if(belong[x]==belong[y]){
  146. for(int j=x;j<=y;j++){
  147. if(b[j]-b[x]>=goal) ans+=(b[j]-b[x]);
  148. }
  149. return;
  150. }
  151. for(register int i=x;i<=r[belong[x]];i++){
  152. if(b[i]-b[x]>=goal) ans+=(b[i]-b[x]);
  153. }
  154. for(register int i=l[belong[y]];i<=y;i++){
  155. if(b[i]-b[x]>=goal) ans+=(b[i]-b[x]);
  156. }
  157. for(register int i=belong[x]+1;i<=belong[y]-1;i++){
  158. register int L=l[i],R=r[i],mid;
  159. while(L<R){
  160. mid=(L+R)/2;
  161. if(gg[mid]-b[x]>=goal){
  162. R=mid;
  163. }
  164. else{
  165. L=mid+1;
  166. }
  167. }
  168. if(L==r[i]){
  169. if(gg[L]-b[x]>=goal){
  170. ans+=gg[L]-b[x];
  171. }
  172. continue;
  173. }
  174. ans+=(sum[r[i]]-sum[L-1]-b[x]*(r[i]-L+1));
  175. }
  176. }
  177. template<class nT>
  178. inline void read(nT& x)
  179. {
  180. char c;
  181. while(c=getchar(),!isdigit(c));
  182. x=c^48;
  183. while(c=getchar(),isdigit(c)) x=x*10+c-48;
  184. }
  185. int main()
  186. {
  187. read(n);
  188. inc(i,2,n){
  189. int u,w; scanf("%d%d",&u,&w);
  190. star[++cnt].add(u,i,w);
  191. }
  192. dfs(1,0);
  193. build();
  194. build2();
  195. int q;read(q);
  196. inc(i,1,q){
  197. ans=0;
  198. long long x,goal;
  199. read(x); read(goal);
  200. query(seg[x],seg[x]+size[x]-1,goal);
  201. printf("%lld\n",ans);
  202. }
  203. }
  204. /*
  205. 3
  206. 1 2
  207. 1 3
  208. 2
  209. 1 3
  210. 1 2
  211.  
  212. 6
  213. 1 2
  214. 1 2
  215. 3 3
  216. 3 4
  217. 2 5
  218. 2
  219. 3 2
  220.  
  221. 7
  222. 3 1
  223. 1 2
  224. 3 1
  225. 4 2
  226. 4 1
  227. 4 2
  228. 5
  229.  
  230. */

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. Transformer的PyTorch实现--转载

    转载自 https://blog.csdn.net/stupid_3/article/details/83184691

  2. 【maven】【spring boot】【单元测试】 使用controller 执行单元测试类

    存在这样一个场景: 当项目启动时间过长,又没办法缩短的时候,写单元测试就是一个十分耗时的工作, 这工作不在于使用编写代码,而在于每次run junit test 都需要完整启动一次项目,白白浪费宝贵的 ...

  3. 图解golang内存分配机制 (转)

    一般程序的内存分配 在讲Golang的内存分配之前,让我们先来看看一般程序的内存分布情况: 以上是程序内存的逻辑分类情况. 我们再来看看一般程序的内存的真实(真实逻辑)图: Go的内存分配核心思想 G ...

  4. Leetcode题目49.字母异位词分组(中等)

    题目描述: 给定一个字符串数组,将字母异位词组合在一起.字母异位词指字母相同,但排列不同的字符串. 示例: 输入: ["eat", "tea", "t ...

  5. Final——PowerShell Empire

    一.介绍 Empire是一款针对Windows平台的.使用PowerShell脚本作为攻击载荷的渗透攻击框架工具,具有从stager生成.提权到渗透维持的一系列功能.Empire实现了无需powers ...

  6. 4 LinkedList

    1 LinkedList public class LinkedList<E> extends AbstractSequentialList<E> implements Lis ...

  7. python安装appium模块

    (base) localhost:~ ligaijiang$ pip3 install Appium-Python-Client Collecting Appium-Python-Client Dow ...

  8. 性能分析 | JVM发生内存溢出的8种原因及解决办法

    推荐阅读:史上最详细JVM与性能优化知识点综合整理 1.Java 堆空间 2.GC 开销超过限制 3.请求的数组大小超过虚拟机限制 4.Perm gen 空间 5.Metaspace 6.无法新建本机 ...

  9. 升级到Android Studio3.x遇到的问题及解决方案

    升级到Android Studio3.x遇到的问题及解决方案 转 https://www.2cto.com/kf/201711/695736.html 升级到Android Studio3.0遇到的问 ...

  10. unix进程间通信方式(下)-unix域套接字(转)

    在之前的博客中已经总结了其它7种进程间的通信方式.unix域套接字用于在同一台计算机上的进程间通信,虽然因特网域套接字可用于同一目的,但是unix域套接字的效率更高.unix域套接字并不进行协议处理, ...