Codeforces 526G Spiders Evil Plan
由于做的时候看的是中文题面,第一遍写就被卡题意了:还以为每一条都要过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的更多相关文章
- Codeforces 526G - Spiders Evil Plan(长链剖分+直径+找性质)
Codeforces 题目传送门 & 洛谷题目传送门 %%%%% 这题也太神了吧 storz 57072 %%%%% 首先容易注意到我们选择的这 \(y\) 条路径的端点一定是叶子节点,否则我 ...
- 【CF526G】Spiders Evil Plan(贪心)
[CF526G]Spiders Evil Plan(贪心) 题面 洛谷 CodeForces 给定一棵树,要求选择\(y\)条链,满足被链覆盖的所有点在树上联通,且\(x\)必定在联通块中. 对于每次 ...
- CF Contest 526 G. Spiders Evil Plan 长链剖分维护贪心
LINK:Spiders Evil Plan 非常巧妙的题目. 选出k条边使得这k条边的路径覆盖x且覆盖的边的边权和最大. 类似于桥那道题还是选择2k个点 覆盖x那么以x为根做长链剖分即可. 不过这样 ...
- [CF526G]Spiders Evil Plan
题目大意: 给出一个$n(n\leq 10^5)$个结点的带边权的树,$q(q\leq 10^5)$个询问,每次询问用$y$条路径覆盖整棵树且覆盖$x$至少一次,最多能覆盖的道路长度是多少? 强制在线 ...
- 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 ...
- 【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 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- 【转载】String和StringBuffer的区别,以及StringBuffer的常用方法介绍
String与StringBuffer的区别简单地说,就是一个变量和常量的关系.StringBuffer对象的内容可以修改:而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象.Stri ...
- Object.prototype.constructor
Returns a reference to the Object function that created the instance's prototype. 注意这个属性的值是函数本省的引用,而 ...
- ios系统的特点
iOS优势 1). 比较稳定,因为他是一个完全封闭的系统,不开源,但是这个系统有他自己严格管理体系,比如app store的app应用:他有自己的评审规则,另外很多软件是需要收费的,这在一定程度上也说 ...
- MTK OTG 流程
一.注册mt_usb驱动 kernel-3.18/drivers/misc/mediatek/usb20/mt6735/usb20.c static int __init usb20_init(voi ...
- 基于微信的SDK的学习与使用——实现产品支付
声明本篇博客为作者原创,本篇是继支付宝支付之后本人又学习的第二种支付实现,本篇着重于原理与注意事项的学习. 参考 参考 微信支付的开发文档相比支付宝的比较简单,但是使用功能丝毫也不含糊,我觉得简单易 ...
- 如何正确遍历删除List中的元素,你会吗?
遍历删除List中的元素有很多种方法,当运用不当的时候就会产生问题.下面主要看看以下几种遍历删除List中元素的形式: 1.通过增强的for循环删除符合条件的多个元素 2.通过增强的for循环删除符合 ...
- codevs-1203
1203 判断浮点数是否相等 题目描述 Description 给出两个浮点数,请你判断这两个浮点数是否相等 输入描述 Input Description 输入仅一行,包含两个浮点数 输出描述 ...
- 【网络爬虫】【java】微博爬虫(五):防止爬虫被墙的几个技巧(总结篇)
爬虫的目的就是大规模地.长时间地获取数据,跟我们正常浏览器获取数据相比,虽然机理相差不大,但总是一个IP去爬网站,大规模集中对服务器访问,时间一长就有可能被拒绝.关于爬虫长时间爬取数据,可能会要求验证 ...
- jQuery 学习笔记(一)jQuery 语法
jQuery 是一个 JavaScript 库,极大地简化了 JavaScript 编程,很容易学习 添加 jQuery 库 <head> <script type="te ...
- windows ping得通,连接不上网
这是被电脑安装的软件拦截的现象,我们只需要使用. netsh winsock reset 重启电脑即可