博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOIP2015 D2T3 洛谷2680 BZOJ4326 运输计划 解题报告
阅读量:5219 次
发布时间:2019-06-14

本文共 3975 字,大约阅读时间需要 13 分钟。

前言:个人认为这是历年NOIP中比较简单的最后一题了,因此将自己的思路与大家分享。

题目大意:

给一棵无根树,给出m条路径。允许将树上的一条边的权值改为0。求m条路径长度最大值的最小值。n,m<=300000.

思考:

题目将40分部分分给了链的情况。50分的部分分给了n,m<=3000.说明以下两点:

  1.链的情况可能是问题的突破口(类比NOIP2016D1T2的部分分设置)。

  2.可能要从较小的n,m入手(经验之谈:当n,m较小有30分时大多情况是为了分数好看,但n,m较小有50-80分则是启发正解)  

那么我们将问题简化成一条链。

对链的情况的分析:

当树退化成链的时候,我们可以将树用链表保存。为了简单起见,我们用映射数组m将链表中距离链头i个结点的编号映射成i+1。链头的编号为1。这样可以将链表保存在普通的数组里,而不是有nxt域的数组。

下文用m(i)表示原来第i个结点的映射。

对于任意询问u,v,必然是从数组的第min(m(v),m(u))个元素到第max(m(u),m(v))个元素。我们可以通过前缀和在O(n)预处理,O(1)的时间获得答案。这样我们得到了未删除边的答案m个。

现在我们要减少一条边的权值到0。不难发现减少的边一定在得到最大答案的路径上。但不一定是得到最大答案的路径上边权最大的边。原因呢?

分析答案式:

最终答案ans=max(w(l1),w(l2),...,w(lm)).w(l)为路径l的长度。当我们减掉的边是最大答案路径上边权最大的边时,答案可能受到次大答案路径的影响。当我们减掉最大答案路径和次大答案路径的交上的最大边时,答案可能受到第三大答案路径的影响。由此分析,答案可能是要减去最大答案路径的最大值,最大答案路径和次大答案路径的交集的最大值,...,所有路径交集的最大值之一。在模拟样例的过程中,我们可以发现答案应该随着上述删除边的变化逐渐变小或不变。若答案变大则可以停止向下查找。

继续链上的分析:

网上的题解大多借着答案的单调性以及要求最大值最小,想到了二分答案。在链上时间复杂度为O(m*logmax).

我比较蠢,没看出来二分答案。我来谈谈我在链上的做法。

将数组放在线段树上,线段树保存三个data。第一个是区间最大值maxx。第二个是区间被所有路径覆盖的最大值chs,第三个是区间最大覆盖次数mxcv。对于任意的l到r。给l到r这一段的区间最大覆盖次数加一。查找操作时如果mxcv不等于当前枚举的路径数量则直接return。否则返回chs。时间复杂度O(mlogn)。

放在树上:

链上的情况解决了,那么树上就很容易了。树链剖分后将问题退化至链上即可解决,时间复杂度需要加一个log,为O(mlognlogn)。

但是不知道为什么我的用时比树上前缀和的O(nlogmaxn)要快

代码:

1 #include
2 using namespace std; 3 const int maxn = 300003; 4 struct edge{
int to,w,nxt;}e[maxn<<1],get_LCA[maxn<<1]; 5 struct node{
int mxcv,maxx,chs,lazy;}t[maxn<<2]; 6 struct ask{
int from,to,LCA,len;}Pro[maxn],*P=Pro; 7 int n,m,NM,NM2,g[maxn],top[maxn],fa[maxn],sz[maxn],son[maxn],ABOUT_LCA[maxn]; 8 int pre[maxn],dep[maxn],call[maxn],abcall[maxn],tms[maxn],FW[maxn],stnd=1,l,r; 9 int found(int x){ 10 int rx = x; while(pre[rx]!=rx)rx=pre[rx]; 11 while(pre[x]!=rx){
int t=pre[x];pre[x]=rx;x=t;} 12 return rx; 13 } 14 void dfs1(int now,int Prt,int DPTH){
//Prt=parent //as we get fa,size,depth,Father_road_weight,we can also get LCA 15 fa[now] = Prt;dep[now] = DPTH;int maxx = 0; 16 for(int i=ABOUT_LCA[now];i;i=get_LCA[i].nxt){ 17 if(!fa[get_LCA[i].to])continue; 18 Pro[get_LCA[i].w].LCA = found(get_LCA[i].to); 19 } 20 for(int i=g[now];i;i=e[i].nxt){ 21 if(e[i].to==Prt)continue; 22 dfs1(e[i].to,now,DPTH+e[i].w); 23 sz[now]+=sz[e[i].to];FW[e[i].to]=e[i].w; 24 if(sz[maxx]
t[now<<1|1].mxcv)t[now].chs=t[now<<1].chs; 63 else if(t[now<<1].mxcv < t[now<<1|1].mxcv)t[now].chs=t[now<<1|1].chs; 64 else t[now].chs = max(t[now<<1].chs,t[now<<1|1].chs); 65 } 66 void push_down(int now){ 67 t[now<<1].lazy+=t[now].lazy;t[now<<1|1].lazy+=t[now].lazy; 68 t[now<<1].mxcv+=t[now].lazy;t[now<<1|1].mxcv+=t[now].lazy; 69 t[now].lazy=0; 70 } 71 int update(int tl,int tr,int now){ 72 if(t[now].mxcv < stnd-1 || l>tr || r
= l && tr <= r){t[now].mxcv++;t[now].lazy++;return t[now].chs;} 74 if(t[now].lazy) push_down(now); 75 int mid=(tl+tr)/2,ans=max(update(tl,mid,now*2),update(mid+1,tr,now*2+1)); 76 push_up(now); 77 return ans; 78 } 79 int ADD_Tree(int OP,int ED,int PB){ 80 int ans = 0; 81 while(OP != PB){ 82 l=call[son[top[OP]]],r=call[OP];int kkk = top[OP]; 83 if(top[OP]==top[PB])l=call[son[PB]],kkk=PB; 84 if(top[OP]==OP){
if(++tms[OP]==stnd)ans=max(ans,FW[OP]);OP=fa[OP];} 85 else{ans=max(ans,update(1,NM,1));OP=kkk;} 86 } 87 while(ED != PB){ 88 l=call[son[top[ED]]],r=call[ED];int kkk = top[ED]; 89 if(top[ED]==top[PB])l=call[son[PB]],kkk=PB; 90 if(top[ED]==ED){
if(++tms[ED]==stnd)ans=max(ans,FW[ED]);ED=fa[ED];} 91 else{ans=max(ans,update(1,NM,1));ED=kkk;} 92 } 93 return ans; 94 } 95 int cmp(ask a,ask b){
return a.len
=1;i--,stnd++){100 int ans = max(P[m].len-ADD_Tree(P[i].from,P[i].to,P[i].LCA),P[i-1].len);101 if(ans > maxans)break; else maxans = ans;102 }103 printf("%d",maxans);104 }105 int main(){read();Heavy_Lt_Dec();work();return 0;}

 

转载于:https://www.cnblogs.com/1-1-1-1/p/7675753.html

你可能感兴趣的文章
CodeForces - 878A Short Program(位运算)
查看>>
路冉的JavaScript学习笔记-2015年1月23日
查看>>
Mysql出现(10061)错误提示的暴力解决办法
查看>>
2018-2019-2 网络对抗技术 20165202 Exp3 免杀原理与实践
查看>>
NPM慢怎么办 - nrm切换资源镜像
查看>>
CoreData 从入门到精通(四)并发操作
查看>>
Swift - UIView的常用属性和常用方法总结
查看>>
Swift - 异步加载各网站的favicon图标,并在单元格中显示
查看>>
Java编程思想总结笔记Chapter 5
查看>>
[LeetCode]662. Maximum Width of Binary Tree判断树的宽度
查看>>
WinForm聊天室
查看>>
【Python学习笔记】1.基础知识
查看>>
梦断代码阅读笔记02
查看>>
selenium学习中遇到的问题
查看>>
大数据学习之一——了解简单概念
查看>>
Linux升级内核教程(CentOS7)
查看>>
Lintcode: Partition Array
查看>>
分享适合个人站长的5类型网站
查看>>
类别的三个作用
查看>>
【SICP练习】85 练习2.57
查看>>