做了 [JSOI2008]Blue Mary开公司 以后发现这 tm 不就是个傻逼树剖+李超线段树吗,做了以后发现我才是傻逼……树剖竟然写错了……这题是我目前写过最长的代码了qwq

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4. typedef long long ll;
  5. int n, m, uu, vv, ww, dep[100005], fa[100005], dfn[100005], son[100005], siz[100005];
  6. int top[100005], idx, dui[100005], opt, ss, tt, cnt, hea[100005];
  7. ll dis[100005];
  8. const ll oo=123456789123456789;
  9. struct Edge{
  10. int too, nxt, val;
  11. }edge[200005];
  12. struct SGT{
  13. ll val[400005], vak[400005], bva[400005];
  14. bool vis[400005];
  15. void pushUp(int o, int lson, int rson){
  16. val[o] = min(val[o], min(val[lson], val[rson]));
  17. }
  18. void build(int o, int l, int r){
  19. val[o] = oo;
  20. if(l==r) ;
  21. else{
  22. int mid=(l+r)>>1;
  23. int lson=o<<1;
  24. int rson=lson|1;
  25. if(l<=mid) build(lson, l, mid);
  26. if(mid<r) build(rson, mid+1, r);
  27. }
  28. }
  29. void updateLichao(int o, int l, int r, ll k, ll b){
  30. ll lvalnow=k*dis[dui[l]]+b;
  31. ll rvalnow=k*dis[dui[r]]+b;
  32. ll lvalpre=vak[o]*dis[dui[l]]+bva[o];
  33. ll rvalpre=vak[o]*dis[dui[r]]+bva[o];
  34. if(!vis[o]){
  35. vis[o] = true;
  36. vak[o] = k; bva[o] = b;
  37. val[o] = min(val[o], min(lvalnow, rvalnow));
  38. return ;
  39. }
  40. else if(lvalnow>=lvalpre && rvalnow>=rvalpre) return ;
  41. else if(lvalnow<lvalpre && rvalnow<rvalpre){
  42. val[o] = min(val[o], min(lvalnow, rvalnow));
  43. vak[o] = k;
  44. bva[o] = b;
  45. }
  46. else{
  47. int mid=(l+r)>>1;
  48. int lson=o<<1;
  49. int rson=lson|1;
  50. ll mvalnow=k*dis[dui[mid]]+b;
  51. ll mvalpre=vak[o]*dis[dui[mid]]+bva[o];
  52. if(lvalnow>=lvalpre){
  53. if(mvalnow>=mvalpre) updateLichao(rson, mid+1, r, k, b);
  54. else{
  55. updateLichao(lson, l, mid, vak[o], bva[o]);
  56. vak[o] = k;
  57. bva[o] = b;
  58. val[o] = min(val[o], min(lvalnow, rvalnow));
  59. }
  60. }
  61. else{
  62. if(mvalnow>=mvalpre) updateLichao(lson, l, mid, k, b);
  63. else{
  64. updateLichao(rson, mid+1, r, vak[o], bva[o]);
  65. vak[o] = k;
  66. bva[o] = b;
  67. val[o] = min(val[o], min(lvalnow, rvalnow));
  68. }
  69. }
  70. pushUp(o, lson, rson);
  71. }
  72. }
  73. void update(int o, int l, int r, int x, int y, ll k, ll b){
  74. if(l>=x && r<=y)
  75. updateLichao(o, l, r, k, b);
  76. else{
  77. int mid=(l+r)>>1;
  78. int lson=o<<1;
  79. int rson=lson|1;
  80. if(x<=mid) update(lson, l, mid, x, y, k, b);
  81. if(mid<y) update(rson, mid+1, r, x, y, k, b);
  82. pushUp(o, lson, rson);
  83. }
  84. }
  85. ll query(int o, int l, int r, int x, int y){
  86. if(l>=x && r<=y) return val[o];
  87. else{
  88. int mid=(l+r)>>1;
  89. int lson=o<<1;
  90. int rson=lson|1;
  91. ll re=oo;
  92. if(vis[o]) re = min(re, min(vak[o]*dis[dui[max(l,x)]]+bva[o], vak[o]*dis[dui[min(r,y)]]+bva[o]));
  93. if(x<=mid) re = min(re, query(lson, l, mid, x, y));
  94. if(mid<y) re = min(re, query(rson, mid+1, r, x, y));
  95. return re;
  96. }
  97. }
  98. }sgt;
  99. void add_edge(int fro, int too, int val){
  100. edge[++cnt].nxt = hea[fro];
  101. edge[cnt].too = too;
  102. edge[cnt].val = val;
  103. hea[fro] = cnt;
  104. }
  105. void dfs1(int x, int f, ll p){
  106. dep[x] = dep[f] + 1;
  107. dis[x] = p;
  108. fa[x] = f;
  109. siz[x] = 1;
  110. int maxSon=-1;
  111. for(int i=hea[x]; i; i=edge[i].nxt){
  112. int t=edge[i].too;
  113. if(t!=f){
  114. dfs1(t, x, p+edge[i].val);
  115. siz[x] += siz[t];
  116. if(siz[t]>maxSon){
  117. son[x] = t;
  118. maxSon = siz[t];
  119. }
  120. }
  121. }
  122. }
  123. void dfs2(int x, int topf){
  124. dfn[x] = ++idx;
  125. top[x] = topf;
  126. dui[idx] = x;
  127. if(!son[x]) return ;
  128. dfs2(son[x], topf);
  129. for(int i=hea[x]; i; i=edge[i].nxt){
  130. int t=edge[i].too;
  131. if(t!=fa[x] && t!=son[x])
  132. dfs2(t, t);
  133. }
  134. }
  135. int getLca(int u, int v){
  136. while(top[u]!=top[v]){
  137. if(dep[top[u]]<dep[top[v]]) swap(u, v);
  138. u = fa[top[u]];
  139. }
  140. if(dep[u]>dep[v]) swap(u, v);
  141. return u;
  142. }
  143. void rangeUpdate(){
  144. int lca=getLca(ss, tt);
  145. int x=ss;
  146. ll nb=uu*dis[x]+vv;
  147. ll nk=-uu;
  148. while(top[x]!=top[lca]){
  149. sgt.update(1, 1, n, dfn[top[x]], dfn[x], nk, nb);
  150. x = fa[top[x]];
  151. }
  152. sgt.update(1, 1, n, dfn[lca], dfn[x], nk, nb);
  153. nb = uu*(dis[ss]-dis[lca]-dis[lca])+vv;
  154. nk = uu;
  155. x = tt;
  156. while(top[x]!=top[lca]){
  157. sgt.update(1, 1, n, dfn[top[x]], dfn[x], nk, nb);
  158. x = fa[top[x]];
  159. }
  160. sgt.update(1, 1, n, dfn[lca], dfn[x], nk, nb);
  161. }
  162. ll rangeQuery(){
  163. ll re=oo;
  164. while(top[ss]!=top[tt]){
  165. if(dep[top[ss]]<dep[top[tt]]) swap(ss, tt);
  166. re = min(re, sgt.query(1, 1, n, dfn[top[ss]], dfn[ss]));
  167. ss = fa[top[ss]];
  168. }
  169. if(dep[ss]>dep[tt]) swap(ss, tt);
  170. re = min(re, sgt.query(1, 1, n, dfn[ss], dfn[tt]));
  171. return re;
  172. }
  173. int main(){
  174. cin>>n>>m;
  175. for(int i=1; i<n; i++){
  176. scanf("%d %d %d", &uu, &vv, &ww);
  177. add_edge(uu, vv, ww);
  178. add_edge(vv, uu, ww);
  179. }
  180. dfs1(1, 0, 0);
  181. dfs2(1, 1);
  182. sgt.build(1, 1, n);
  183. while(m--){
  184. scanf("%d", &opt);
  185. if(opt==1){
  186. scanf("%d %d %d %d", &ss, &tt, &uu, &vv);
  187. rangeUpdate();
  188. }
  189. else{
  190. scanf("%d %d", &ss, &tt);
  191. printf("%lld\n", rangeQuery());
  192. }
  193. }
  194. return 0;
  195. }

loj2032 「SDOI2016」游戏的更多相关文章

  1. 【LOJ】#2032. 「SDOI2016」游戏

    题解 看错题了,以为单次修改相当于一个覆盖,后来才明白"添加"-- 就相当于添加很多线段求最小值 首先这个等差数列添加的方式比较烦人,我们拆开两条链,一条s到lca,一条lca到t ...

  2. LOJ_2305_「NOI2017」游戏 _2-sat

    LOJ_2305_「NOI2017」游戏 _2-sat 题意: 给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个 ...

  3. 「SDOI2016」储能表(数位dp)

    「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...

  4. 「HNOI2018」游戏

    「HNOI2018」游戏 解题思路 首先没有锁上的门可以缩点缩掉,然后对于一扇锁上的门,如果钥匙在左边,那么右边就永远不可能到达左边,同理如果钥匙在右边,左边就永远不可能到达右边. 然后考虑一个暴力的 ...

  5. 「NOI2017」游戏

    「NOI2017」游戏 题目描述 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 \(A\).\(B\).\ ...

  6. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...

  7. LOJ2305 「NOI2017」游戏

    「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...

  8. [LOJ 2070] 「SDOI2016」平凡的骰子

    [LOJ 2070] 「SDOI2016」平凡的骰子 [题目链接] 链接 [题解] 原题求的是球面面积 可以理解为首先求多面体重心,然后算球面多边形的面积 求重心需要将多面体进行四面体剖分,从而计算出 ...

  9. liberOJ #2033. 「SDOI2016」生成魔咒 后缀数组

    #2033. 「SDOI2016」生成魔咒     题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 11.2 22 拼凑起来形成一个魔咒串 [1,2] [1, 2] ...

随机推荐

  1. 适配器模式和php实现

    1. 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 解决的问题 即Adapter模式使得原本由于接口不兼容而不 ...

  2. restframework安装及APIView分析

    一.restframework的安装 方式一:pip3 install djangorestframework 方式二:pycharm图形化界面安装 方式三:pycharm命令行下安装(装在当前工程所 ...

  3. 两个页面实现mui轮播图与选项卡结合

    index.html页面 <!DOCTYPE html><html><head> <meta charset="utf-8"> &l ...

  4. Ubuntu 设置静态ip地址

    1. 找到文件并作如下修改: sudo vim /etc/network/interfaces 修改如下部分: auto eth0iface eth0 inet staticaddress 192.1 ...

  5. 手机QQ访问时,html页面在QQ中自定义预览和自定义分享

    手机QQ访问时,html页面在QQ中自定义预览和自定义分享 有一天,产品说要做个自定义预览和分享功能,于是很快在微信上实现了,可是不知道在QQ上怎么实现,查看了很多网站,最后才找到了解决方案,于是想和 ...

  6. SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题

    转自  :SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题 问题: 1. System.Data.SqlClient.SqlExcepti ...

  7. 打开某exe提示"应用程序无法启动,因为应用程序的并行配置不正确……"的解决方案

    本人在新安装好了的windows server 2008 r2 (64位)上运行“RefilesName V2.0(文件批量改名).exe”,结果提示: 应用程序无法启动,因为应用程序的并行配置不正确 ...

  8. codeforce Gym 100500I Hall of Fame (水)

    题意:统计一些串中,字母的出现频率,不分大小写,找出现频率最高5个字符(相同频率优先取字典序大的),把他们的对应的值加起来判断以下是否大于62. 没出现的不算. #include<cstdio& ...

  9. CDOJ 490 UESTC 490 Swap Game(思路,逆序对)

    题意:有两种颜色的小球形成环,求最小交互次数使球相连. 题解:先解决另一个简单的问题,如果是一个链,把红球标记为1,蓝球标记为0,要排成升序需要多少次交换呢?答案是逆序对总数,原因是一次交互最多消除一 ...

  10. 10.1 plan

    1951    [Sdoi2010]古代猪文  Sdoi2010 Contest2   807 1928 1566    [NOI2009]管道取珠       806 1429 2756    [S ...