【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\)子树内的最深叶子。要么就是找到其祖先中第一个有叶子被选中的点,删去其中的一个儿子的贡献。

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

#include<iostream>
#include<cstdio>
using namespace std;
#define mp make_pair
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,Q,lans;
struct Line{int v,next,w;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
#define lson (now<<1)
#define rson (now<<1|1)
#define fr first
#define sd second
int mxv,rt,p[19][MAX],dfn[MAX],low[MAX],ln[MAX],md[MAX],dep[MAX],tim;
void dfs(int u,int ff)
{
p[0][u]=ff;ln[dfn[u]=++tim]=u;md[u]=dep[u];
for(int i=1;i<19;++i)p[i][u]=p[i-1][p[i-1][u]];
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;
dep[v]=dep[u]+e[i].w;dfs(v,u);
md[u]=max(md[u],md[v]);
}
low[u]=tim;
}
pair<int,int> mx[MAX<<2];int tag[MAX<<2];
void pushup(int now){mx[now]=max(mx[lson],mx[rson]);}
void Build(int now,int l,int r)
{
if(l==r){mx[now]=mp(dep[ln[l]],ln[l]);return;}
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
pushup(now);
}
void Modify(int now,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R){mx[now].fr+=w;tag[now]+=w;return;}
int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,w);
if(R>mid)Modify(rson,mid+1,r,L,R,w);
pushup(now);mx[now].fr+=tag[now];
}
int ans[MAX],vis[MAX];
void pre(int _rt)
{
rt=_rt;dfs(rt,0);Build(1,1,n);
for(int i=2;i<=n;++i)
{
ans[i]=ans[i-1]+mx[1].fr;
for(int j=mx[1].sd;j&&!vis[j];j=p[0][j])
vis[j]=i,Modify(1,1,n,dfn[j],low[j],dep[p[0][j]]-dep[j]);
}
}
int Solve(int x,int y)
{
y=min(y,n);if(vis[x]<=y)return ans[y];int u=x;
for(int i=18;~i;--i)if(vis[p[i][x]]>y)x=p[i][x];
x=p[0][x];
return ans[y]+md[u]-dep[x]-min(dep[x],min(ans[y]-ans[y-1],md[x]-dep[x]));
}
void DFS(int u,int ff,int dep)
{
if(dep>mxv)mxv=dep,rt=u;
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=ff)DFS(e[i].v,u,dep+e[i].w);
}
int main()
{
n=read();Q=read();
for(int i=1,u,v,w;i<n;++i)u=read(),v=read(),w=read(),Add(u,v,w),Add(v,u,w);
mxv=0;DFS(1,0,0);pre(rt);
while(Q--)
{
int u=(read()+lans-1)%n+1,v=(read()+lans-1)%n+1;
printf("%d\n",lans=Solve(u,v<<1));
}
return 0;
}

【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. 后台管理系统之系统运行日志开发(Java实现)

    一,实现运行日志记录在文件中,并实现日志分包记录,项目出问题后方便定位分析.效果如图: 二,代码实现(springboot项目) 只需要在resources目录下新建:logback-spring.x ...

  2. PhpStorm 头部注释、类注释和函数注释的设置

    *设置位置:"Settings"->"file templates"; 如下图,设置头部注释.类注释以及函数注释,时间.用户名.文件名称等随机改变的属性, ...

  3. 设置SQLServer数据库内存

    需要设置SQLServer数据库的内存配置.登录数据库,这里使用的是SQLServer2008,右键点击最上方的服务器名,在弹出的菜单中,点击属性] 打开服务器属性窗口.默认显示的是第一项[常规]内容 ...

  4. 2.请介绍一下List和ArrayList的区别,ArrayList和HashSet区别

    第一问: List是接口,ArrayList实现了List接口. 第二问: ArrayList实现了List接口,HashSet实现了Set接口,List和Set都是继承Collection接口. A ...

  5. Flutter上拉加载下拉刷新---flutter_easyrefresh

    前言 Flutter默认不支持上拉加载,下拉刷新也仅仅支持Material的一种样式.Android开发使用过SmartRefreshLayout的小伙伴都知道这是一个强大的刷新UI库,集成了很多出色 ...

  6. nodejs 利用zip-local模块压缩文件夹

    var zipper = require("zip-local"); zipper.sync.zip("./folder").compress().save(& ...

  7. Navicat 远程连接Docker容器中的mysql 报错:1251 - Client does not support authentication protocol 解决办法。

    出现这个问题 首先进入 1.docker exec -it mysql02 bash      //mysql02是mysql容器的别名 2.mysql -uroot -p 3.输入密码 4.进入my ...

  8. James 3.1服务器的安装与搭建

    参考:1. ububtu下基于docker安装配置Apache James 3.1.0: https://blog.csdn.net/bonwei/article/details/83061372 2 ...

  9. docker学习笔记一

    知识点: 1)docker简介 2)docker安装,仓库配置 3)docker仓库镜像拉取,导出,导入,删除 4)docker容器操作,容器的创建,删除,运行,停止,日志查看等. 5)  docke ...

  10. 关于IWMS中遇到的问题及解决方法

    1.生成的文章上传到外网上,但是没一会儿又变成原来的样子? 解决方案:把上传页面对应的template中的.aspx页面也要上传到外网去.