由于做的时候看的是中文题面,第一遍写就被卡题意了:还以为每一条都要过x,那么就是一道动态树根选择2y个叶子的奇怪题目

交完0分gg,才发现题目看错了╮(╯▽╰)╭

the node containing the candy is adjacent to at least one rope covered with a web

完全就是两道题啊。。。。。


首先考虑没有x的做法

贪心显然是对的

1.直径一定要取,否则一定可以通过把与直径最接近(以直径一段为根的lca深度最大)的一条路径改为直径来改善答案

2.剩下的一定从大取到小贪心取(在每次取完后更新每个的数据情况下),同理可证明

然后就可以通过“长链剖分”(把重链剖分里的子树大小改为最深的带权深度)解决没有x的问题了

(目测蛮好写的)

然后考虑一定要把x包含进去

然后是不会证但是感觉很对还能A的想法(⊙﹏⊙)b:

1.先把直径和前2(y-1)【因为每条路径都可以跨两条支链,但是选直径还需要一条路径】大的支链拉进答案(形成一棵树)

2.把x加入答案有两种方案:

  把离x最近的一条边切掉一半和x所在链连成一条边

  删掉最短的一条边把x所在链加入答案

——上图中黑色和灰色表示考虑x前做出的答案,红色表示考虑x后加上的边,灰色表示考虑x后去掉的边,左右图分别表示了两种考虑的姿势

两种方案去个比较好的,O(∩_∩)O搞定啦!


实现什么的。。。我是这么写的:

先找直径,拉出来存起来,然后把剩下的(应该是一个大森林)每个节点深度算出来(把直径上的点深度看做0)

瞎搞一波即可,没什么数据结构

 #include <bits/stdc++.h>
using namespace std;
int n,tot,lend,post,lengthd,m,N,p,q,o,x,y,lord;
int fir[],nex[],dis[],to[],len[],d[],sum_d[],rank[];
int fa[],best[],dep[],top[],ans[],sum[];
void add(int p,int q,int o)
{
nex[++N]=fir[p];len[N]=o;to[N]=q;fir[p]=N;
}
void Dfs(int now)
{
for(int i=fir[now];i;i=nex[i])
if(!dis[to[i]])
{
dis[to[i]]=dis[now]+len[i];
Dfs(to[i]);
}
}
void dfs(int now)
{
for(int i=;i<=n;i++)
dis[i]=;
dis[now]=;
Dfs(now);
}
void build(int now,int fat,int deep)
{
fa[now]=fat;best[now]=deep;dep[now]=deep;rank[now]=lord;
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fat)
{
build(to[i],now,deep+len[i]);
best[now]=max(best[now],best[to[i]]);
}
}
void pou(int now,int Top)
{
bool sad=;top[now]=Top;
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fa[now])
if(sad && best[now]==best[to[i]])
sad=,pou(to[i],Top);
else
pou(to[i],to[i]);
if(sad)
ans[++tot]=dep[now]-dep[fa[top[now]]];
}
void find_d()
{
dfs();int start=,bes=,end=;
for(int i=;i<=n;i++)
if(dis[i]>bes) bes=dis[i],start=i;
dfs(start);bes=;
for(int i=;i<=n;i++)
if(dis[i]>bes) bes=dis[i],end=i;
for(d[lend=]=post=end;post!=start;d[++lend]=post,rank[post]=lend)
for(int i=fir[post];i;i=nex[i])
if(dis[to[i]]<dis[post])
{
post=to[i];
break;
}
lengthd=dis[end]-;
for(int i=;i<=lend;i++)
sum_d[i]=dis[d[i]]-;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
scanf("%d%d%d",&p,&q,&o),
add(p,q,o),add(q,p,o);
find_d();
for(int i=;i<=lend;i++)
for(int j=fir[d[i]];j;j=nex[j])
{
if(i> && to[j]==d[i-]) continue;
if(i<lend && to[j]==d[i+]) continue;
lord=i;
build(to[j],d[i],len[j]);
pou(to[j],to[j]);
}
sort(ans+,ans+tot+,greater<int>());
for(int i=;i<=tot;i++)
sum[i]=sum[i-]+ans[i];
int lastans=;
if()
{
for(int i=;i<=lend;i++)
printf("%d ",d[i]);
puts("");
}
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(x== && y==)
int e=;
x=(x+lastans-)%n+;y=(y+lastans-)%n+;
y=y*-;
if(y>=tot)
{
lastans=sum[tot]+lengthd;
printf("%d\n",lastans);
}
else
if(!y)
if(!dep[x])
{
lastans=lengthd;
printf("%d\n",lastans);
}
else
{
lastans=best[x]+max(sum_d[rank[x]],lengthd-sum_d[rank[x]]);
printf("%d\n",lastans);
}
else
if(dep[x] && best[x]-dep[fa[top[x]]]<ans[y])
{
lastans=lengthd+sum[y-];
int enter=x;
while(dep[enter] && best[enter]-dep[fa[top[enter]]]<ans[y])
enter=fa[top[enter]];
if(dep[enter])
lastans+=max(best[x]-dep[enter],best[x]-best[enter]+ans[y]);
else
{
lastans+=best[x];
if(ans[y]>min(sum_d[rank[x]],lengthd-sum_d[rank[x]]))
lastans+=ans[y]-min(sum_d[rank[x]],lengthd-sum_d[rank[x]]);
}
printf("%d\n",lastans);
}
else
{
lastans=sum[y]+lengthd;
printf("%d\n",sum[y]+lengthd);
}
}
return ;
}

写的又臭又长╮(╯▽╰)╭

Codeforces 526G Spiders Evil Plan的更多相关文章

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

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

  2. 【CF526G】Spiders Evil Plan(贪心)

    [CF526G]Spiders Evil Plan(贪心) 题面 洛谷 CodeForces 给定一棵树,要求选择\(y\)条链,满足被链覆盖的所有点在树上联通,且\(x\)必定在联通块中. 对于每次 ...

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

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

  4. [CF526G]Spiders Evil Plan

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

  5. 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 ...

  6. 【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 ...

  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. 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 ...

  9. 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 ...

随机推荐

  1. 【转载】String和StringBuffer的区别,以及StringBuffer的常用方法介绍

    String与StringBuffer的区别简单地说,就是一个变量和常量的关系.StringBuffer对象的内容可以修改:而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象.Stri ...

  2. Object.prototype.constructor

    Returns a reference to the Object function that created the instance's prototype. 注意这个属性的值是函数本省的引用,而 ...

  3. ios系统的特点

    iOS优势 1). 比较稳定,因为他是一个完全封闭的系统,不开源,但是这个系统有他自己严格管理体系,比如app store的app应用:他有自己的评审规则,另外很多软件是需要收费的,这在一定程度上也说 ...

  4. MTK OTG 流程

    一.注册mt_usb驱动 kernel-3.18/drivers/misc/mediatek/usb20/mt6735/usb20.c static int __init usb20_init(voi ...

  5. 基于微信的SDK的学习与使用——实现产品支付

    声明本篇博客为作者原创,本篇是继支付宝支付之后本人又学习的第二种支付实现,本篇着重于原理与注意事项的学习. 参考  参考 微信支付的开发文档相比支付宝的比较简单,但是使用功能丝毫也不含糊,我觉得简单易 ...

  6. 如何正确遍历删除List中的元素,你会吗?

    遍历删除List中的元素有很多种方法,当运用不当的时候就会产生问题.下面主要看看以下几种遍历删除List中元素的形式: 1.通过增强的for循环删除符合条件的多个元素 2.通过增强的for循环删除符合 ...

  7. codevs-1203

    1203 判断浮点数是否相等 题目描述 Description 给出两个浮点数,请你判断这两个浮点数是否相等   输入描述 Input Description 输入仅一行,包含两个浮点数   输出描述 ...

  8. 【网络爬虫】【java】微博爬虫(五):防止爬虫被墙的几个技巧(总结篇)

    爬虫的目的就是大规模地.长时间地获取数据,跟我们正常浏览器获取数据相比,虽然机理相差不大,但总是一个IP去爬网站,大规模集中对服务器访问,时间一长就有可能被拒绝.关于爬虫长时间爬取数据,可能会要求验证 ...

  9. jQuery 学习笔记(一)jQuery 语法

    jQuery 是一个 JavaScript 库,极大地简化了 JavaScript 编程,很容易学习 添加 jQuery 库 <head> <script type="te ...

  10. windows ping得通,连接不上网

    这是被电脑安装的软件拦截的现象,我们只需要使用.   netsh winsock reset   重启电脑即可