• 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)

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

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 int n,tot,lend,post,lengthd,m,N,p,q,o,x,y,lord;
      4 int fir[100001],nex[200001],dis[100001],to[200001],len[200001],d[100001],sum_d[100001],rank[100001];
      5 int fa[100001],best[100001],dep[100001],top[100001],ans[100001],sum[100001];
      6 void add(int p,int q,int o)
      7 {
      8     nex[++N]=fir[p];len[N]=o;to[N]=q;fir[p]=N;
      9 }
     10 void Dfs(int now)
     11 {
     12     for(int i=fir[now];i;i=nex[i])
     13     if(!dis[to[i]])
     14     {
     15         dis[to[i]]=dis[now]+len[i];
     16         Dfs(to[i]);
     17     }
     18 }
     19 void dfs(int now)
     20 {
     21     for(int i=1;i<=n;i++)
     22         dis[i]=0;
     23     dis[now]=1;
     24     Dfs(now);
     25 }
     26 void build(int now,int fat,int deep)
     27 {
     28     fa[now]=fat;best[now]=deep;dep[now]=deep;rank[now]=lord;
     29     for(int i=fir[now];i;i=nex[i])
     30     if(to[i]!=fat)
     31     {
     32         build(to[i],now,deep+len[i]);
     33         best[now]=max(best[now],best[to[i]]);
     34     }
     35 }
     36 void pou(int now,int Top)
     37 {
     38     bool sad=1;top[now]=Top;
     39     for(int i=fir[now];i;i=nex[i])
     40     if(to[i]!=fa[now])
     41         if(sad && best[now]==best[to[i]])
     42             sad=0,pou(to[i],Top);
     43         else
     44             pou(to[i],to[i]);
     45     if(sad)
     46         ans[++tot]=dep[now]-dep[fa[top[now]]];
     47 }
     48 void find_d()
     49 {
     50     dfs(1);int start=0,bes=0,end=0;
     51     for(int i=1;i<=n;i++)
     52         if(dis[i]>bes) bes=dis[i],start=i;
     53     dfs(start);bes=0;
     54     for(int i=1;i<=n;i++)
     55         if(dis[i]>bes) bes=dis[i],end=i;
     56     for(d[lend=1]=post=end;post!=start;d[++lend]=post,rank[post]=lend)
     57         for(int i=fir[post];i;i=nex[i])
     58             if(dis[to[i]]<dis[post])
     59             {
     60                 post=to[i];
     61                 break;
     62             }
     63     lengthd=dis[end]-1;
     64     for(int i=2;i<=lend;i++)
     65         sum_d[i]=dis[d[i]]-1;
     66 }
     67 int main()
     68 {
     69     scanf("%d%d",&n,&m);
     70     for(int i=1;i<n;i++)
     71         scanf("%d%d%d",&p,&q,&o),
     72         add(p,q,o),add(q,p,o);
     73     find_d();
     74     for(int i=1;i<=lend;i++)
     75         for(int j=fir[d[i]];j;j=nex[j])
     76         {
     77             if(i>1 && to[j]==d[i-1]) continue;
     78             if(i<lend && to[j]==d[i+1]) continue;
     79             lord=i;
     80             build(to[j],d[i],len[j]);
     81             pou(to[j],to[j]);
     82         }
     83     sort(ans+1,ans+tot+1,greater<int>());
     84     for(int i=1;i<=tot;i++)
     85         sum[i]=sum[i-1]+ans[i];
     86     int lastans=0;
     87     if(0)
     88     {
     89         for(int i=1;i<=lend;i++)
     90             printf("%d ",d[i]);
     91         puts("");
     92     } 
     93     for(int i=1;i<=m;i++)
     94     {
     95         scanf("%d%d",&x,&y);
     96         if(x==7 && y==2)
     97             int e=1;
     98         x=(x+lastans-1)%n+1;y=(y+lastans-1)%n+1;
     99         y=y*2-2;
    100         if(y>=tot)
    101         {
    102             lastans=sum[tot]+lengthd;
    103             printf("%d
    ",lastans);
    104         }
    105         else
    106         if(!y)
    107             if(!dep[x])
    108             {
    109                 lastans=lengthd;
    110                 printf("%d
    ",lastans);
    111             }
    112             else
    113             {
    114                 lastans=best[x]+max(sum_d[rank[x]],lengthd-sum_d[rank[x]]);
    115                 printf("%d
    ",lastans);
    116             }
    117         else
    118         if(dep[x] && best[x]-dep[fa[top[x]]]<ans[y])
    119         {
    120             lastans=lengthd+sum[y-1];
    121             int enter=x;
    122             while(dep[enter] && best[enter]-dep[fa[top[enter]]]<ans[y])
    123                 enter=fa[top[enter]];
    124             if(dep[enter])
    125                 lastans+=max(best[x]-dep[enter],best[x]-best[enter]+ans[y]);
    126             else
    127             {
    128                 lastans+=best[x];
    129                 if(ans[y]>min(sum_d[rank[x]],lengthd-sum_d[rank[x]]))
    130                     lastans+=ans[y]-min(sum_d[rank[x]],lengthd-sum_d[rank[x]]);
    131             }
    132             printf("%d
    ",lastans);
    133         }
    134         else
    135         {
    136             lastans=sum[y]+lengthd;
    137             printf("%d
    ",sum[y]+lengthd);
    138         }
    139     }
    140     return 0;
    141 }

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

  • 相关阅读:
    倒计时功能的实现
    getElementsByClassName
    模拟滚动条
    display:table-cell
    gulp相关知识(2)
    gulp相关知识(1)
    移动端的网页试做
    关于移动端的布局
    伪类before和after
    简单时钟——css3
  • 原文地址:https://www.cnblogs.com/wanglichao/p/6480629.html
Copyright © 2020-2023  润新知