由于做的时候看的是中文题面,第一遍写就被卡题意了:还以为每一条都要过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. POJ 2485 Highways(最小生成树+ 输出该最小生成树里的最长的边权)

                                                                                                         ...

  2. 转载的C#学习笔记

    转载地址:http://www.cnblogs.com/renyanlei/p/4075065.html 最近在一个培训机构里面教授Net知识.每天都会带领学生学习c#知识.我希望把每天学习的笔记记录 ...

  3. html5--5-9 绘制扇形

    html5--5-9 绘制扇形 学习要点 综合运用已经学过的知识绘制一个扇形 矩形的绘制方法 rect(x,y,w,h)创建一个矩形 strokeRect(x,y,w,hx,y,w,h) 绘制矩形(无 ...

  4. yii的增删改查

    要想实现数据库的操作,必须首先初始化数据模型. 一.yii的数据库模型的初始化有两种.第一种是利用模型的静态方法model:第二种是实例化一个新的模型.以例子说明: //数据的查询关键代码 $good ...

  5. ACM2016级新生第三周训练赛

    本次是弱校题解-比赛链接 备用链接 题目还是比较基础,比较简单.认真补题,学会学习. A -人见人爱A^B 题解: 求 A的B次方,我们可以用循环进行累乘操作,进而计算出次方.因为题目要求只需要求出最 ...

  6. SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三维偏序)

    Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it ...

  7. JavaScript ES6中export、export default、import用法和区别

    相信熟悉JS ES6的同学都知道export.export default是导出,import是导入的意思. 那么问题就来了, 1.import 导入要怎么用? 2.export.export def ...

  8. VS中文档大纲视图的作用

    一.在vs的菜单栏中点击视图==========>其他窗口===========>文档大纲 二.文档大纲的作用是可以查看当前Form窗体的结构,如下图 三.若果感觉控件的类型太长,可以在文 ...

  9. ubuntu12.04下安装搜狗拼音

    Ubuntu 12.04 LTS 版本   由于 Ubuntu 12.04 LTS 自带的 Fcitx 版本较旧,需要先通过 PPA 升级,才能安装下载的 deb 软件包.   1. 点击左上角的图标 ...

  10. system(“pause”)和getchar()

    大家都知道system(“PAUSE”)可以让C程序在运行结束之前暂停运行.用system(“PAUSE”)可以解决运行程序一闪而过,看不到输出结果的问题.有程序员会用system(“PAUSE”)只 ...