1. /*
  2. 树链刨分+离线操作
  3. 题意:给你一棵树,和询问x,y
  4. 从节点x--节点1的小于等于y的最大值.
  5. 解:先建一个空树,将树的边权值从小到大排序,将询问y按从小到大排序
  6. 对于每次询问y将小于等于y的边权值的边加入,在进行询问将结果储存最后输出即可
  7. 易错点:要考虑到节点1到节点1的情况需特判。
  8. */
  9. #pragma comment(linker, "/STACK:102400000,102400000")
  10. #include<stdio.h>
  11. #include<string.h>
  12. #include<math.h>
  13. #include<algorithm>
  14. #include<iostream>
  15. using namespace std;
  16. #define N 110000
  17. #define inf 0x3fffffff
  18. int f[N];
  19. int top[N];
  20. int fa[N];
  21. int siz[N];
  22. int nu,yong;
  23. int head[N];
  24. int deep[N];
  25. int son[N];
  26. int w[N];
  27. int Max;
  28. struct node
  29. {
  30. int u,v,w,next,we;
  31. } bian[N*4],ff[N],fy[N];
  32. void init()
  33. {
  34. yong=nu=0;
  35. memset(head,-1,sizeof(head));
  36. memset(son,-1,sizeof(son));
  37. }
  38. void addedge(int u,int v,int w)
  39. {
  40. bian[yong].u=u;
  41. bian[yong].v=v;
  42. bian[yong].w=w;
  43. bian[yong].next=head[u];
  44. head[u]=yong++;
  45. }
  46. void dfs(int u,int father,int d)
  47. {
  48. deep[u]=d;
  49. fa[u]=father;
  50. siz[u]=1;
  51. int i;
  52. for(i=head[u]; i!=-1; i=bian[i].next)
  53. {
  54. int v=bian[i].v;
  55. if(v!=father)
  56. {
  57. dfs(v,u,d+1);
  58. siz[u]+=siz[v];
  59. if(son[u]==-1||siz[son[u]]<siz[v])
  60. son[u]=v;
  61. }
  62. }
  63. return ;
  64. }
  65. void getnu(int u,int cnt)
  66. {
  67. f[u]=nu++;
  68. top[u]=cnt;
  69. if(son[u]==-1)return ;
  70. getnu(son[u],cnt);
  71. int i;
  72. for(i=head[u]; i!=-1; i=bian[i].next)
  73. {
  74. int v=bian[i].v;
  75. if(v!=son[u]&&v!=fa[u])
  76. getnu(v,v);
  77. }
  78. return ;
  79. }
  80. int cmp(const void *a,const void *b)
  81. {
  82. return (*(struct node *)a).v-(*(struct node *)b).v;
  83. }
  84. int cmpp(const void *a,const void *b)
  85. {
  86. return (*(struct node *)a).w-(*(struct node *)b).w;
  87. }
  88. struct nodee
  89. {
  90. int l,r,maxx;
  91. } tree[N*4];
  92. int Ma(int v,int vv)
  93. {
  94. return v>vv?v:vv;
  95. }
  96. void pushup(int t)
  97. {
  98. tree[t].maxx=Ma(tree[t*2].maxx,tree[t*2+1].maxx);
  99. }
  100. void build(int t,int l,int r)
  101. {
  102. tree[t].l=l;
  103. tree[t].r=r;
  104. if(tree[t].l==tree[t].r)
  105. {
  106. tree[t].maxx=-1;
  107. return ;
  108. }
  109. int mid=(tree[t].l+tree[t].r)/2;
  110. build(t*2,l,mid);
  111. build(t*2+1,mid+1,r);
  112. pushup(t);
  113. }
  114. void update(int t,int x,int y)
  115. {
  116. if(tree[t].l==x&&tree[t].r==x)
  117. {
  118. tree[t].maxx=y;
  119. return ;
  120. }
  121. int mid=(tree[t].l+tree[t].r)/2;
  122. if(x<=mid)update(t*2,x,y);
  123. else
  124. update(t*2+1,x,y);
  125. pushup(t);
  126. }
  127. void qury(int t,int l,int r)
  128. {
  129. if(tree[t].l==l&&tree[t].r==r)
  130. {
  131. Max=Ma(Max,tree[t].maxx);
  132. return ;
  133. }
  134. int mid=(tree[t].l+tree[t].r)/2;
  135. if(r<=mid)qury(t*2,l,r);
  136. else if(l>mid)qury(t*2+1,l,r);
  137. else
  138. {
  139. qury(t*2,l,mid);
  140. qury(t*2+1,mid+1,r);
  141. }
  142. pushup(t);
  143. }
  144. int findmax(int u,int v)
  145. {
  146. if(u==v)return -1;//特判因为可能出现节点1到节点1的情况是不存在的
  147. int f1=top[u];
  148. int f2=top[v];
  149. int ans=-inf;
  150. while(f1!=f2)
  151. {
  152. if(deep[f1]<deep[f2])
  153. {
  154. swap(f1,f2);
  155. swap(u,v);
  156. }
  157. Max=-inf;
  158. qury(1,f[f1],f[u]);
  159. ans=Ma(ans,Max);
  160. u=fa[f1];
  161. f1=top[u];
  162. }
  163. if(u==v)return ans;
  164. if(deep[u]>deep[v]) swap(u,v);
  165. Max=-inf;
  166. qury(1,f[son[u]],f[v]);
  167. ans=Ma(ans,Max);
  168. return ans;
  169. }
  170. int main()
  171. {
  172. int n,i,j,k,t;
  173. scanf("%d",&t);
  174. while(t--)
  175. {
  176. scanf("%d",&n);
  177. init();
  178. for(i=1; i<n; i++)
  179. {
  180. scanf("%d%d%d",&ff[i].u,&ff[i].v,&ff[i].w);
  181. addedge(ff[i].u,ff[i].v,ff[i].w);
  182. addedge(ff[i].v,ff[i].u,ff[i].w);
  183. }
  184. dfs(1,1,0);//得到deep,fa,siz,son数组值
  185. getnu(1,1);//得到f,top的值
  186. for(i=1; i<n; i++)
  187. {
  188. if(deep[ff[i].u]<deep[ff[i].v])
  189. swap(ff[i].u,ff[i].v);
  190. w[ff[i].u]=ff[i].w;
  191. }
  192. build(1,1,nu-1);//建空树
  193. scanf("%d",&k);
  194. for(i=1; i<=k; i++)
  195. {
  196. scanf("%d%d",&fy[i].u,&fy[i].v);
  197. fy[i].w=i;//记录下标
  198. }
  199. qsort(fy+1,k,sizeof(fy[0]),cmp);//排序
  200. qsort(ff+1,n-1,sizeof(ff[0]),cmpp);
  201. for(i=1,j=1; i<=k; i++)
  202. {
  203. for(; j<n;)
  204. {
  205. if(fy[i].v>=ff[j].w)
  206. update(1,f[ff[j].u],ff[j].w);//加边
  207. else break;
  208. j++;
  209. }
  210. fy[i].we=findmax(1,fy[i].u);//查找
  211. }
  212. qsort(fy+1,k,sizeof(fy[0]),cmpp);//再次按下标排序
  213. for(i=1; i<=k; i++)//输出
  214. printf("%d\n",fy[i].we);
  215. }
  216. return 0;
  217. }

hdu 3804树链剖分+离线操作的更多相关文章

  1. hdu 3804 树链剖分

    思路:将边权排序,然后插入线段树,这样就可以直接用二分查找确定答案. #pragma comment(linker, "/STACK:1024000000,1024000000") ...

  2. hdu 5893 (树链剖分+合并)

    List wants to travel Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/O ...

  3. hdu 5052 树链剖分

    Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  4. hdu 4897 树链剖分(重轻链)

    Little Devil I Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  5. hdu 5274 树链剖分

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  6. HDU 3966 (树链剖分+线段树)

    Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...

  7. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  8. HDU 3966 /// 树链剖分+树状数组

    题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...

  9. hdu 4729 树链剖分

    思路:这个树链剖分其实还是比较明显的.将边按权值排序后插入线段树,然后用线段树查找区间中比某个数小的数和,以及这样的数的个数.当A<=B时,就全部建新的管子. 对于A>B的情况比较 建一条 ...

随机推荐

  1. printf的整型

    参 数 说  明 %d 输出数字长为变量数值的实际长度 %md 输出m位(不足补空格,大于m位时按实际长度输出) %-md m含义同上.左对齐输出 %ld l(小写字母)表示输出“长整型”数据 %m1 ...

  2. Android项目模块化遇到的问题

    1.问题背景 gradle 4 MacOs 10.14.3 Android Studio 3 在android模块化的时候,例如,有两个模块,一个是usercenter,另一个是common. 其中u ...

  3. SPFA+Dinic HDOJ 5294 Tricks Device

    题目传送门 /* 题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路 SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cn ...

  4. ACM_走楼梯Ⅱ

    走楼梯Ⅱ Time Limit: 2000/1000ms (Java/Others) Problem Description: 有一楼梯共N+1级,刚开始时你在第一级,若每次能走M级(1<=M& ...

  5. Using 10053 Trace Events and get outline

    When it comes to performance tuning, we can spend time on one or both ends of the problem. On the &q ...

  6. JavaScript 正则表达式(转自 mozilla)

    正则表达式是被用来匹配字符串中的字符组合的模式.在JavaScript中,正则表达式也是对象. 这种模式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match.r ...

  7. 全面学习ORACLE Scheduler特性(5)Schedules调度Programs执行的Jobs

    3.2 Schedules调度Programs执行的Jobs 通过schedule调度program的执行的job,看到这样的形容是不是让你彻底晕头了,就说明你还是没搞明白10g中SCHEDULERS ...

  8. 全面学习ORACLE Scheduler特性(2)管理jobs

    1.2  管理Jobs 1.2.1  启用Jobs 前面创建JOB时,由于未显式的指定ENABLED参数,因此即使指定了START_DATE,不过默认情况下JOB不会自动执行.对于这种情况,DBMS_ ...

  9. CSS + radius 五环

    使用CSS的外链方式,写了一个五环 CSS的布局 附加radius的使用 思路: 一个大盒子里放两个子盒子: 两个子盒子上下排列,分别放3个和2个盒子用来制作圆环: 大盒子给相对定位,连个子盒子设为绝 ...

  10. LN : leetcode 3 Longest Substring Without Repeating Characters

    lc 3 Longest Substring Without Repeating Characters 3 Longest Substring Without Repeating Characters ...