传送门

考虑只有一个询问,怎么使用暴力枚举最快的得到答案.因为要求最大的,所以可以把链按权值从大往小排序,然后往后扫,找到一个没有交的就是答案,直接退出

一堆询问,可以考虑整体二分,先二分一个值\(mid\),然后从前往后扫,如果是加入/删除操作,并且权值\(> mid\)就把这个操作贡献记上;如果是询问,然后如果经过这个点的链个数\(\ne\)当前存在的链个数,说明答案\(>mid\),否则\(\le mid\)

然后剩下的套一个整体二分板子就好了.答案的话如果取值范围的\(l=r\),就可以直接更新答案.然后就是怎么算经过某个点的链条数,显然可以使用洛谷树链剖分模板题的代码(别用无脑线段树,这里只要单点求值),或者考虑树上差分,每次询问子树内权值和就是那个链条数

  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. #define db double
  4. #define il inline
  5. #define re register
  6. using namespace std;
  7. const int N=2e5+10;
  8. il int rd()
  9. {
  10. int x=0,w=1;char ch=0;
  11. while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  12. while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  13. return x*w;
  14. }
  15. int to[N],nt[N],hd[N],tot=1;
  16. il void add(int x,int y)
  17. {
  18. ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
  19. ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
  20. }
  21. int fa[N],sz[N],de[N],hs[N],top[N],dfn[N],ti;
  22. void dfs1(int x)
  23. {
  24. sz[x]=1;
  25. for(int i=hd[x];i;i=nt[i])
  26. {
  27. int y=to[i];
  28. if(y==fa[x]) continue;
  29. fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
  30. hs[x]=sz[hs[x]]>sz[y]?hs[x]:y;
  31. }
  32. }
  33. void dfs2(int x,int ntp)
  34. {
  35. dfn[x]=++ti,top[x]=ntp;
  36. if(hs[x]) dfs2(hs[x],ntp);
  37. for(int i=hd[x];i;i=nt[i])
  38. {
  39. int y=to[i];
  40. if(y==fa[x]||y==hs[x]) continue;
  41. dfs2(y,y);
  42. }
  43. }
  44. int n,q;
  45. int c[N];
  46. void ad(int x,int y){while(x<=n) c[x]+=y,x+=x&(-x);}
  47. int gsm(int x){int an=0;while(x) an+=c[x],x-=x&(-x);return an;}
  48. void add(int x,int y,int z)
  49. {
  50. while(top[x]!=top[y])
  51. {
  52. if(de[top[x]]<de[top[y]]) swap(x,y);
  53. ad(dfn[top[x]],z),ad(dfn[x]+1,-z);
  54. x=fa[top[x]];
  55. }
  56. if(de[x]>de[y]) swap(x,y);
  57. ad(dfn[x],z),ad(dfn[y]+1,-z);
  58. }
  59. struct node
  60. {
  61. int x,y,z,k;
  62. }p[N],lp[N],rp[N];
  63. int an[N],m;
  64. void dc(int l,int r,int lx,int rx)
  65. {
  66. if(l>r||lx>rx) return;
  67. int sd=0;
  68. if(lx==rx)
  69. {
  70. for(int i=l;i<=r;++i)
  71. {
  72. if(p[i].k) sd+=p[i].k,add(p[i].x,p[i].y,p[i].k);
  73. else if(gsm(dfn[p[i].x])!=sd) an[p[i].y]=lx;
  74. }
  75. for(int i=l;i<=r;++i)
  76. if(p[i].k) sd+=p[i].k,add(p[i].x,p[i].y,-p[i].k);
  77. return;
  78. }
  79. int mid=(lx+rx)>>1;
  80. int tl=0,tr=0;
  81. for(int i=l;i<=r;++i)
  82. {
  83. if(p[i].k)
  84. {
  85. if(p[i].z<=mid) lp[++tl]=p[i];
  86. else
  87. {
  88. sd+=p[i].k;
  89. rp[++tr]=p[i],add(p[i].x,p[i].y,p[i].k);
  90. }
  91. }
  92. else
  93. {
  94. if(gsm(dfn[p[i].x])==sd) lp[++tl]=p[i];
  95. else
  96. {
  97. rp[++tr]=p[i];
  98. }
  99. }
  100. }
  101. for(int i=1;i<=tl;++i) p[l+i-1]=lp[i];
  102. for(int i=1;i<=tr;++i) p[l+tl+i-1]=rp[i];
  103. for(int i=1;i<=tr;++i)
  104. if(rp[i].k) add(rp[i].x,rp[i].y,-rp[i].k);
  105. dc(l,l+tl-1,lx,mid),dc(l+tl,r,mid+1,rx);
  106. }
  107. int main()
  108. {
  109. n=rd(),q=rd();
  110. for(int i=1;i<n;++i) add(rd(),rd());
  111. dfs1(1),dfs2(1,1);
  112. for(int i=1;i<=q;++i)
  113. {
  114. int op=rd();
  115. if(op==0) p[i].x=rd(),p[i].y=rd(),p[i].z=rd(),p[i].k=1;
  116. else if(op==1)
  117. {
  118. int x=rd();
  119. p[i]=p[x],p[i].k=-1;
  120. }
  121. else p[i].x=rd(),an[p[i].y=++m]=-1;
  122. }
  123. dc(1,q,0,1<<30);
  124. for(int i=1;i<=m;++i) printf("%d\n",an[i]);
  125. return 0;
  126. }

luogu P3250 [HNOI2016]网络的更多相关文章

  1. P3250 [HNOI2016]网络

    LINK:网络 一棵树 每次添加一条路径 或者删除之前的一条路径 或询问除了不经过某个点之外剩下的最大值. 一个显然的思路 对于一条路径的权值我们直接把权值塞上去 标记永久化一下即可. 考虑如何求答案 ...

  2. 洛咕P3250 [HNOI2016]网络 整体二分

    这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...

  3. [洛谷P3250][HNOI2016]网络

    题目大意:给定一棵树.有三种操作: $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输. $1\;x:$结束第$x$个数据传输. $2\;x:$询问不经过点$x$的数据传输中 ...

  4. 洛谷P3250 [HNOI2016]网络(整体二分+树状数组+树剖)

    传送门 据说正解是树剖套堆???然而代码看着稍微有那么一点点长…… 考虑一下整体二分,设当前二分到的答案为$mid$,如果所有大于$mid$的边都经过当前点$x$,那么此时$x$的答案必定小于等于$m ...

  5. 并不对劲的bzoj4538:loj2049:p3250:[HNOI2016]网络

    题意 有一棵\(n\)(\(n\leq 10^5\))个点的树,\(m\)(\(m\leq 2\times 10^5\))个操作.操作有三种:1.给出\(u,v,k\),表示加入一条从\(u\)到\( ...

  6. P3250 [HNOI2016] 网络 (树剖+堆/整体二分+树上差分+树状数组)

    解法1: 本题有插入路径和删除路径,在每个节点维护插入堆和删除堆,查询时两者top一样则一直弹出.如果每个节点维护的是经过他的路径,显然有些不好处理,正难则反,每个点维护不经过他的路径,那么x节点出了 ...

  7. BZOJ 4538: [Hnoi2016]网络 [整体二分]

    4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...

  8. 【LG3250】[HNOI2016]网络

    [LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...

  9. 4538: [Hnoi2016]网络

    4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...

随机推荐

  1. tyvj/joyoi 1336 火车进栈

    比原题水了很多(因为原题要高精度) 输出字典序前20种出栈序列. 其实是贪心题:我们每次确定一个出栈的数. 当栈里有数时,字典序显然比从后面拿数要小,所以先搜这个. 之后依次搜后面队列里的数,因为字典 ...

  2. (五)Oracle 的 oracle 表查询

    http://www.hechaku.com/Oracle/oracle_tables_chack.html 通过scott用户下的表来演示如何使用select语句,接下来对emp.dept.salg ...

  3. django orm 重点大全

    1.最简单的跨表,查询外键表中符合主表条件的记录列表 #用户类型表 class User_typ(models.Model): name=models.CharField(max_length=32) ...

  4. 最短路 次短路 k短路(k很小)

    最短路 luogu 3371 https://www.luogu.org/problemnew/show/P3371 #include <cstdio> #include <cstd ...

  5. pytest 8 参数化parametrize

    pytest.mark.parametrize装饰器可以实现用例参数化 1.以下是一个实现检查一定的输入和期望输出测试功能的典型例子 import pytest @pytest.mark.parame ...

  6. increment/decrement/dereference操作符

    标题以上分别对于++/--/* #include <iostream> #include <cstddef> using namespace std; class INT { ...

  7. Codeforces Round #525 (Div. 2) C. Ehab and a 2-operation task

    传送门 https://www.cnblogs.com/violet-acmer/p/10068786.html 题意: 给定一个长度为 n 的数组a[ ],并且有两种操作: ①将前 i 个数全都加上 ...

  8. JS事件(一)事件流&事件处理程序

    1.事件流描述的是从页面接收事件的顺序 IE和Netscape提出了几乎完全相反的事件流概念 IE:事件冒泡(由内而外) Netscape:事件捕获(由外向内) DOM2级事件规定事件流包括三个阶段: ...

  9. 一名全栈设计师的Mac工具箱(设计,开发,效率)

        我喜欢把自己定义为一个会一些设计的全栈工程师.在一些大型企业项目中,我一般担任架构师的角色,而到了我自己负责的个人或开源项目中,我就成了一名全栈设计师.我喜欢用自学而来的那些设计技能进行网站或 ...

  10. 获取日k数据

    http://web.ifzq.gtimg.cn/appstock/app/fqkline/get?_var=kline_dayqfq&param=sz002921,day,,,320,qfq ...