【CF526G】Spiders Evil Plan(贪心)

题面

洛谷

CodeForces

给定一棵树,要求选择\(y\)条链,满足被链覆盖的所有点在树上联通,且\(x\)必定在联通块中。

对于每次询问最大化被链覆盖的边的权值和。

强制在线。

题解

假设我们只有一次询问,会怎么做?

显然以\(x\)为根,如果\(x\)的度数大于\(1\),那么可以转化为选择\(2y\)个叶子节点,这样子一定存在一种方案满足链并恰好是\(x\)到这\(2y\)个节点的链的并。

如果\(x\)的度数为\(1\)的话,显然就选择\(2y-1\)个点来做上述操作。

我们发现直径的一个端点必定会被选中。

那么我们把问题转化一下,以直径\((a,b)\)的端点\(a,b\)中任意一个点为根来考虑这个问题,不妨以\(a\)为根来考虑。

首先我们选择\(y\)条链的答案就是选择\(2y-1\)个叶子节点的答案。但是还需要钦定\(x\)在方案内。

那么分类讨论一下,如果\(x\)的子树中存在一个叶子被选入了答案,那么就不用管了。

否则,我们必须替换一个点转而选择\(x\)子树中的一个叶子,加入点\(x\)的贡献我们可以很容易的算出,现在的问题转变成了如何找到删去的最小贡献。注意这里加入\(x\)之后删去每个点的贡献就会改变。

那么这样子只有两种情况,要么是删去最后一个加入答案的叶子,替换为\(x\)子树内的最深叶子。要么就是找到其祖先中第一个有叶子被选中的点,删去其中的一个儿子的贡献。

维护每次选择哪个叶子的时候,可以线段树考虑,也可以长链剖分+贪心。

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. #define mp make_pair
  5. #define MAX 100100
  6. inline int read()
  7. {
  8. int x=0;bool t=false;char ch=getchar();
  9. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  10. if(ch=='-')t=true,ch=getchar();
  11. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  12. return t?-x:x;
  13. }
  14. int n,Q,lans;
  15. struct Line{int v,next,w;}e[MAX<<1];
  16. int h[MAX],cnt=1;
  17. inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
  18. #define lson (now<<1)
  19. #define rson (now<<1|1)
  20. #define fr first
  21. #define sd second
  22. int mxv,rt,p[19][MAX],dfn[MAX],low[MAX],ln[MAX],md[MAX],dep[MAX],tim;
  23. void dfs(int u,int ff)
  24. {
  25. p[0][u]=ff;ln[dfn[u]=++tim]=u;md[u]=dep[u];
  26. for(int i=1;i<19;++i)p[i][u]=p[i-1][p[i-1][u]];
  27. for(int i=h[u];i;i=e[i].next)
  28. {
  29. int v=e[i].v;if(v==ff)continue;
  30. dep[v]=dep[u]+e[i].w;dfs(v,u);
  31. md[u]=max(md[u],md[v]);
  32. }
  33. low[u]=tim;
  34. }
  35. pair<int,int> mx[MAX<<2];int tag[MAX<<2];
  36. void pushup(int now){mx[now]=max(mx[lson],mx[rson]);}
  37. void Build(int now,int l,int r)
  38. {
  39. if(l==r){mx[now]=mp(dep[ln[l]],ln[l]);return;}
  40. int mid=(l+r)>>1;
  41. Build(lson,l,mid);Build(rson,mid+1,r);
  42. pushup(now);
  43. }
  44. void Modify(int now,int l,int r,int L,int R,int w)
  45. {
  46. if(L<=l&&r<=R){mx[now].fr+=w;tag[now]+=w;return;}
  47. int mid=(l+r)>>1;
  48. if(L<=mid)Modify(lson,l,mid,L,R,w);
  49. if(R>mid)Modify(rson,mid+1,r,L,R,w);
  50. pushup(now);mx[now].fr+=tag[now];
  51. }
  52. int ans[MAX],vis[MAX];
  53. void pre(int _rt)
  54. {
  55. rt=_rt;dfs(rt,0);Build(1,1,n);
  56. for(int i=2;i<=n;++i)
  57. {
  58. ans[i]=ans[i-1]+mx[1].fr;
  59. for(int j=mx[1].sd;j&&!vis[j];j=p[0][j])
  60. vis[j]=i,Modify(1,1,n,dfn[j],low[j],dep[p[0][j]]-dep[j]);
  61. }
  62. }
  63. int Solve(int x,int y)
  64. {
  65. y=min(y,n);if(vis[x]<=y)return ans[y];int u=x;
  66. for(int i=18;~i;--i)if(vis[p[i][x]]>y)x=p[i][x];
  67. x=p[0][x];
  68. return ans[y]+md[u]-dep[x]-min(dep[x],min(ans[y]-ans[y-1],md[x]-dep[x]));
  69. }
  70. void DFS(int u,int ff,int dep)
  71. {
  72. if(dep>mxv)mxv=dep,rt=u;
  73. for(int i=h[u];i;i=e[i].next)
  74. if(e[i].v!=ff)DFS(e[i].v,u,dep+e[i].w);
  75. }
  76. int main()
  77. {
  78. n=read();Q=read();
  79. for(int i=1,u,v,w;i<n;++i)u=read(),v=read(),w=read(),Add(u,v,w),Add(v,u,w);
  80. mxv=0;DFS(1,0,0);pre(rt);
  81. while(Q--)
  82. {
  83. int u=(read()+lans-1)%n+1,v=(read()+lans-1)%n+1;
  84. printf("%d\n",lans=Solve(u,v<<1));
  85. }
  86. return 0;
  87. }

【CF526G】Spiders Evil Plan(贪心)的更多相关文章

  1. [CF526G]Spiders Evil Plan

    题目大意: 给出一个$n(n\leq 10^5)$个结点的带边权的树,$q(q\leq 10^5)$个询问,每次询问用$y$条路径覆盖整棵树且覆盖$x$至少一次,最多能覆盖的道路长度是多少? 强制在线 ...

  2. CF Contest 526 G. Spiders Evil Plan 长链剖分维护贪心

    LINK:Spiders Evil Plan 非常巧妙的题目. 选出k条边使得这k条边的路径覆盖x且覆盖的边的边权和最大. 类似于桥那道题还是选择2k个点 覆盖x那么以x为根做长链剖分即可. 不过这样 ...

  3. Codeforces 526G Spiders Evil Plan

    由于做的时候看的是中文题面,第一遍写就被卡题意了:还以为每一条都要过x,那么就是一道动态树根选择2y个叶子的奇怪题目 交完0分gg,才发现题目看错了╮(╯▽╰)╭ the node containin ...

  4. Codeforces 526G - Spiders Evil Plan(长链剖分+直径+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 %%%%% 这题也太神了吧 storz 57072 %%%%% 首先容易注意到我们选择的这 \(y\) 条路径的端点一定是叶子节点,否则我 ...

  5. code forces 383 Arpa's loud Owf and Mehrdad's evil plan(有向图最小环)

    Arpa's loud Owf and Mehrdad's evil plan time limit per test 1 second memory limit per test 256 megab ...

  6. Arpa's loud Owf and Mehrdad's evil plan

    Arpa's loud Owf and Mehrdad's evil plan time limit per test 1 second memory limit per test 256 megab ...

  7. Codeforces Round #383 (Div. 2)C. Arpa's loud Owf and Mehrdad's evil plan

    C. Arpa's loud Owf and Mehrdad's evil plan time limit per test 1 second memory limit per test 256 me ...

  8. Codeforces Round #383 (Div. 2) C. Arpa's loud Owf and Mehrdad's evil plan —— DFS找环

    题目链接:http://codeforces.com/contest/742/problem/C C. Arpa's loud Owf and Mehrdad's evil plan time lim ...

  9. 【codeforces 742C】Arpa's loud Owf and Mehrdad's evil plan

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

随机推荐

  1. pycharm设置pytest运行程序

  2. django的配置文件字符串是怎么导入的?

    写在开头: 每个APP都会有配置文件,像下代码Django等等这种的settings里面的配置导入都是字符串的,他们是怎么做的呢? MIDDLEWARE = [ 'django.middleware. ...

  3. Ubuntu Linux Recovery Mode

    在安全模式/修復模式有以下的選項︰resume Resume normal boot繼續正常啟動作業,供不小心誤入此選單的使用者開機使用.(继续以正常模式启动) clean Try to make f ...

  4. JEECG框架中使用Flash版本Uploadify,在Chrome版本号70下无法启动的解决办法

    感谢文章:https://www.cnblogs.com/zinan/p/6902427.html 单独打开IFRAME中的页面 点击导航栏的<不安全> 再刷新单独IFRAME的页面,就可 ...

  5. jenkins 插件介绍

    1.jenkins 利用maven编译,打包,所需插件:Maven Integration: Maven集成插件这个插件提供了Jenkins和Maven的深度集成,无论是好还是坏:项目之间的自动触发取 ...

  6. 小程序wepy.js框架总结

    wepy.js借鉴了Vue的语法风格和功能特性,对官方提供的框架进行了封装,更贴近于MVVM架构模式,让开发者更加容易上手,增加开发效率.(脏数据处理--是否有标识.是否有响应) 前端开发的对组件化开 ...

  7. JQuery动态修改样式

    JQuery动态修改样式 SetStyle(); function SetStyle() { $(".toolbar").remove(); $(".placeholde ...

  8. C# 父子页面传值

    业务需求是:父页面点击“选择任务”按钮进入任务列表页.(项目进度周报) 父页面如下: 任务列表页: 选择某一个任务,点击“确定”后返回父页面所需数据. 父页面“选择任务” 按钮触发事件. /// &l ...

  9. AngularJS基于模块化的MVC实现

    AngularJS基于模块化的MVC实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&qu ...

  10. Eclipse中修改jsp、html……的编码格式

    一般如果使用的是Eclipse的默认编码格式,在我们保存的时候会提示选择保存的编码格式,保存后英文没有问题,但是中文就会乱码. 修改方式是: Windows——>Preferences——> ...