bzoj题面

  • Time limit 10000 ms
  • Memory limit 265216 kB
  • OS Linux

吐槽

又浪费一个下午……区间乘-1之后,最大值和最小值更新有坑。新的最大值是原来最小值乘-1,新的最小值是原来最大值乘-1。

没脸见人了

树链剖分,但这题的权值在边上不在点上,那我们只需要在dfs过程中把边权搞到下方的点上,然后两点间各种操作时,不对两点LCA进行操作就好(见代码里一串/)

听说LCT处理这个更擅长,留坑

源代码

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<algorithm>
  5. const int MAXN=2e4+5;
  6. int n,q;
  7. struct Edge{
  8. int nxt,to,w,id;
  9. }e[MAXN<<1];
  10. int head[MAXN],cnt=1;
  11. inline void add(int u,int v,int w,int id)
  12. {
  13. e[cnt]={head[u],v,w,id};
  14. head[u]=cnt++;
  15. e[cnt]={head[v],u,w,id};
  16. head[v]=cnt++;
  17. }
  18. int bridge[MAXN];//用桥的id查询点
  19. struct Tree{
  20. int w;
  21. int fa,dep,sz,wson;
  22. int id,top;
  23. }t[MAXN];
  24. void dfs1(int u,int fa,int eid)
  25. {
  26. t[u].w=e[eid].w;
  27. bridge[e[eid].id]=u;
  28. t[u].fa=fa;
  29. t[u].dep=t[t[u].fa].dep+1;
  30. t[u].sz=1;
  31. int mxson=-1;
  32. for(int i=head[u];i;i=e[i].nxt)
  33. {
  34. int v=e[i].to;
  35. if(fa==v) continue;
  36. dfs1(v,u,i);
  37. int temp=t[v].sz;
  38. if(temp>mxson)
  39. {
  40. t[u].wson=v;
  41. mxson=temp;
  42. }
  43. t[u].sz+=temp;
  44. }
  45. }
  46. int a[MAXN],id=1;
  47. void dfs2(int u,int top)
  48. {
  49. t[u].top=top;
  50. t[u].id=id;
  51. a[id]=t[u].w;
  52. id++;
  53. if(t[u].sz==1) return;
  54. dfs2(t[u].wson,top);
  55. for(int i=head[u];i;i=e[i].nxt)
  56. {
  57. int v=e[i].to;
  58. if(v==t[u].wson||v==t[u].fa) continue;
  59. dfs2(v,v);
  60. }
  61. }
  62. struct Segtree{
  63. int sum;
  64. int mx;
  65. int mn;
  66. bool lazy;//乘-1的
  67. }s[MAXN<<2];
  68. inline void pushup(int x)
  69. {
  70. s[x].sum=s[x<<1].sum+s[x<<1|1].sum;
  71. s[x].mx=std::max(s[x<<1].mx,s[x<<1|1].mx);
  72. s[x].mn=std::min(s[x<<1].mn,s[x<<1|1].mn);
  73. }
  74. void build(int x,int l,int r)
  75. {
  76. if(l==r)
  77. {
  78. s[x]={a[l],a[l],a[l],0};
  79. return;
  80. }
  81. int mid=l+r>>1;
  82. build(x<<1,l,mid);
  83. build(x<<1|1,mid+1,r);
  84. pushup(x);
  85. }
  86. inline void pushdown(int x)
  87. {
  88. if(!s[x].lazy) return;
  89. s[x<<1].lazy=!s[x<<1].lazy;
  90. int temp=s[x<<1].mx;
  91. s[x<<1].mx=-s[x<<1].mn;
  92. s[x<<1].mn=-temp;
  93. s[x<<1].sum*=-1;
  94. s[x<<1|1].lazy=!s[x<<1|1].lazy;
  95. temp=s[x<<1|1].mx;
  96. s[x<<1|1].mx=-s[x<<1|1].mn;
  97. s[x<<1|1].mn=-temp;
  98. s[x<<1|1].sum*=-1;
  99. s[x].lazy=0;
  100. }
  101. void mul(int x,int l,int r,int ql,int qr)//区间乘-1
  102. {
  103. if(ql<=l&&r<=qr)
  104. {
  105. s[x].lazy=!s[x].lazy;
  106. int temp=s[x].mx;
  107. s[x].mx=-s[x].mn;
  108. s[x].mn=-temp;
  109. s[x].sum*=-1;
  110. return;
  111. }
  112. pushdown(x);
  113. int mid=l+r>>1;
  114. if(ql<=mid) mul(x<<1,l,mid,ql,qr);
  115. if(qr>mid) mul(x<<1|1,mid+1,r,ql,qr);
  116. pushup(x);
  117. }
  118. void change(int x,int l,int r,int pos,int k)
  119. {
  120. if(l==r)
  121. {
  122. s[x].mn=k;
  123. s[x].mx=k;
  124. s[x].sum=k;
  125. return;
  126. }
  127. pushdown(x);
  128. int mid=l+r>>1;
  129. if(pos<=mid) change(x<<1,l,mid,pos,k);
  130. else change(x<<1|1,mid+1,r,pos,k);
  131. pushup(x);
  132. }
  133. int quesum(int x,int l,int r,int ql,int qr)
  134. {
  135. if(ql<=l&&r<=qr) return s[x].sum;
  136. int mid=l+r>>1;
  137. int ans=0;
  138. pushdown(x);
  139. if(ql<=mid) ans+=quesum(x<<1,l,mid,ql,qr);
  140. if(qr>mid) ans+=quesum(x<<1|1,mid+1,r,ql,qr);
  141. return ans;
  142. }
  143. int quemx(int x,int l,int r,int ql,int qr)
  144. {
  145. if(ql<=l&&r<=qr) return s[x].mx;
  146. int mid=l+r>>1;
  147. int ans=-99999999;
  148. pushdown(x);
  149. if(ql<=mid) ans=std::max(quemx(x<<1,l,mid,ql,qr),ans);
  150. if(qr>mid) ans=std::max(quemx(x<<1|1,mid+1,r,ql,qr),ans);
  151. return ans;
  152. }
  153. int quemn(int x,int l,int r,int ql,int qr)
  154. {
  155. if(ql<=l&&r<=qr) return s[x].mn;
  156. int mid=l+r>>1;
  157. int ans=99999999;
  158. pushdown(x);
  159. if(ql<=mid) ans=std::min(quemn(x<<1,l,mid,ql,qr),ans);
  160. if(qr>mid) ans=std::min(quemn(x<<1|1,mid+1,r,ql,qr),ans);
  161. return ans;
  162. }
  163. void optn(int x,int y)
  164. {
  165. while(t[x].top!=t[y].top)
  166. {
  167. if(t[t[x].top].dep<t[t[y].top].dep)
  168. std::swap(x,y);
  169. mul(1,1,n,t[t[x].top].id,t[x].id);
  170. x=t[t[x].top].fa;
  171. }
  172. if(x==y) return;
  173. if(t[x].id>t[y].id) std::swap(x,y);
  174. mul(1,1,n,t[x].id+1,t[y].id);///////////////////////////////////////////////////////////////////
  175. }
  176. int optsum(int x,int y)
  177. {
  178. int ans=0;
  179. while(t[x].top!=t[y].top)
  180. {
  181. if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
  182. ans+=quesum(1,1,n,t[t[x].top].id,t[x].id);
  183. x=t[t[x].top].fa;
  184. }
  185. if(x==y) return ans;
  186. if(t[x].id>t[y].id) std::swap(x,y);
  187. ans+=quesum(1,1,n,t[x].id+1,t[y].id);
  188. return ans;
  189. }
  190. int optmx(int x,int y)
  191. {
  192. int ans=-99999999;
  193. while(t[x].top!=t[y].top)
  194. {
  195. if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
  196. ans=std::max(ans,quemx(1,1,n,t[t[x].top].id,t[x].id));
  197. x=t[t[x].top].fa;
  198. }
  199. if(x==y) return ans;
  200. if(t[x].id>t[y].id) std::swap(x,y);
  201. ans=std::max(ans,quemx(1,1,n,t[x].id+1,t[y].id));
  202. return ans;
  203. }
  204. int optmn(int x,int y)
  205. {
  206. int ans=99999999;
  207. while(t[x].top!=t[y].top)
  208. {
  209. if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
  210. ans=std::min(ans,quemn(1,1,n,t[t[x].top].id,t[x].id));
  211. x=t[t[x].top].fa;
  212. }
  213. if(x==y) return ans;
  214. if(t[x].id>t[y].id) std::swap(x,y);
  215. ans=std::min(ans,quemn(1,1,n,t[x].id+1,t[y].id));
  216. return ans;
  217. }
  218. int main()
  219. {
  220. //freopen("test.in","r",stdin);
  221. scanf("%d",&n);
  222. for(int i=1,u,v,w;i<n;i++)
  223. {
  224. scanf("%d%d%d",&u,&v,&w);
  225. add(u+1,v+1,w,i);
  226. }
  227. dfs1(1,0,0);
  228. dfs2(1,1);
  229. build(1,1,n);
  230. scanf("%d",&q);
  231. //for(int i=1;i<n;i++)
  232. //printf("%d ",bridge[i]);
  233. //puts("");
  234. while(q--)
  235. {
  236. char opt[10];
  237. int u,v;
  238. scanf("%s%d%d",opt,&u,&v);
  239. if(opt[0]=='C')
  240. change(1,1,n,t[bridge[u]].id,v);
  241. else if(opt[0]=='N') optn(u+1,v+1);
  242. else if(opt[0]=='S')
  243. printf("%d\n",optsum(u+1,v+1));
  244. else if(opt[1]=='A')
  245. printf("%d\n",optmx(u+1,v+1));
  246. else printf("%d\n",optmn(u+1,v+1));
  247. }
  248. return 0;
  249. }

洛谷 P1505 BZOJ 2157 [国家集训队]旅游的更多相关文章

  1. 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】

    P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...

  2. 【洛谷】1494:[国家集训队]小Z的袜子【莫队】

    P1494 [国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… ...

  3. 洛谷P1903 数颜色 [国家集训队] 莫队

    正解:带修莫队 解题报告: 可以理解为引入时间参数,然后就是有了仨参数,关于这个修改同样的是,如果时间是相同的,不用搞,如果时间不相同做一下时光倒流/时光推移就成嘛 但是肯定既然这样的话,按照原来的s ...

  4. 题解 洛谷P1903/BZOJ2120【[国家集训队]数颜色 / 维护队列】

    对于不会树套树.主席树的本蒟蒻,还是老老实实的用莫队做吧.... 其实这题跟普通莫队差不了多远,无非就是有了一个时间,当我们按正常流程排完序后,按照基本的莫队来,做莫队时每次循环对于这一次操作,我们在 ...

  5. 题解 洛谷P1501/BZOJ2631【[国家集训队]Tree II】

    Link-Cut-Tree 的懒标记下传正确食用方法. 我们来逐步分析每一个操作. 1:+ u v c:将u到v的路径上的点的权值都加上自然数c; 解决方法: 很显然,我们可以 split(u,v) ...

  6. 洛谷 P1505 [国家集训队]旅游 解题报告

    P1505 [国家集训队]旅游 题目描述 \(\tt{Ray}\) 乐忠于旅游,这次他来到了\(T\)城.\(T\)城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游 ...

  7. 树链剖分【洛谷P1505】 [国家集训队]旅游

    P1505 [国家集训队]旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城 ...

  8. 洛谷 P1505 [国家集训队]旅游 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...

  9. luoguP1505 [国家集训队]旅游(真的毒瘤)

    luogu P1505 [国家集训队]旅游 题目 #include<iostream> #include<cstdio> #include<cstdlib> #in ...

随机推荐

  1. Java并发ReadWriteLock接口

    java.util.concurrent.locks.ReadWriteLock接口允许一次读取多个线程,但一次只能写入一个线程. 读锁 - 如果没有线程锁定ReadWriteLock进行写入,则多线 ...

  2. Java学习开发第三阶段总结

    第三阶段的学习总结: 在这次学习我学习了面向对象和封装的知识. ①类的定义 package day01; public class student { //成员变量 String name; //姓名 ...

  3. PERCONA-TOOLKIT 安装 使用

    1.基于MySQL主从环境 可以参考https://www.cnblogs.com/xianglei_/p/12068241.html 上传rpm包 并安装 1 2 cd /usr/local/src ...

  4. ORACLE 使用通配符进行字符串截取

    ORACLE 使用通配符进行字符串截取 select regexp_substr('aa--a(1-23),b---b(32---1)','[^(,)]+',1,1) as col1, regexp_ ...

  5. oracle group by rollup实现小计、合计

    SQL合计汇总实现数据N+1条显示: 注意group by rollup((ename, job, empno))!!! select decode(grouping(ename) + groupin ...

  6. 【6.28校内test】T2 【音乐会】二重变革

    [音乐会]二重变革[题目链接] T2其实是一道数学题,因为你看: 2MB??一共就可以存下个int,然鹅再看数据范围: 那么大是稳稳的不是TLE就是MLE了,所以肯定是数学题,而且是只需要存很少数据的 ...

  7. HDU 3182 ——A Magic Lamp(思维)

    Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lam ...

  8. Python文件的几种读写方式

    1). "w "写模式,它是不能读的,如果用w模式打开一个已经存在的文件,会清空以前的文件内容,重新写 "w+ "是读写内容,只要沾上w,肯定会清空原来的文件2 ...

  9. async 异步抓取 花瓣网高清大图 30s爬取500张

    废话 不多说,直接上代码,不懂得看注释 先安装  pip install aiohttp "异步抓取花瓣网图片" # pip install aiohttp import requ ...

  10. 机器学习及scikit-learn

    一.机器学习以及scikit-learn 1. 机器学习基本步骤: (1)定义一系列函数  =>   (2)定义函数的优劣  =>  (3)选择最优函数 2.什么是scikit-learn ...