zoukankan      html  css  js  c++  java
  • [BZOJ2002][Hnoi2010]Bounce 弹飞绵羊

    2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 10814  Solved: 5562
    [Submit][Status][Discuss]

    Description

    某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

    Input

    第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    Output

    对于每个i=1的情况,你都要输出一个需要的步数,占一行。

    Sample Input

    4
    1 2 1 1
    3
    1 1
    2 1 1
    1 1

    Sample Output

    2
    3
     
     
     
    一看到此题就想到了递推+分块,写完后莫名WA了2次后来才发现修改时能将绵羊弹飞的节点的to数组没归0.
    后来看题解发现正解是动态树(LCT)蒟蒻的我并不会写,这里贴出分块代码
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 int read()
     9 {
    10     char ch=getchar();int x=0,f=1;
    11     while(!isdigit(ch)){if(ch=='-')f=-1; ch=getchar();}
    12     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int n;
    16 int a[200002];
    17 int belong[200002],to[200002],b[200002];
    18 int size;
    19 int main()
    20 {
    21     n=read();
    22     size=sqrt(n);
    23     for(int i=1;i<=n;i++)
    24     {
    25         a[i]=read();
    26         belong[i]=(i-1)/size+1;
    27     }
    28     for(int i=n;i>=1;i--)
    29     {
    30         if(i+a[i]>n) b[i]=1;
    31         else if(belong[i]==belong[i+a[i]]){b[i]=b[i+a[i]]+1;to[i]=to[i+a[i]];}
    32         else{b[i]=1;to[i]=i+a[i];}
    33     }
    34     int m=read();
    35     while(m--)
    36     {
    37         int ask=read();
    38         if(ask==1)
    39         {
    40             int now=read();
    41             now++;
    42             int ans=0;
    43             while(now)
    44             {
    45                 ans+=b[now];
    46                 now=to[now];
    47             }
    48             printf("%d
    ",ans);
    49         }
    50         else
    51         {
    52             int now=read(),c=read();
    53             now++;
    54             a[now]=c;
    55             int bn=belong[now];
    56             for(int i=now;belong[i]==bn;i--)
    57             {
    58                 if(i+a[i]>n) b[i]=1,to[i]=0;
    59                 else if(belong[i]==belong[i+a[i]]){b[i]=b[i+a[i]]+1;to[i]=to[i+a[i]];}
    60                 else{b[i]=1;to[i]=i+a[i];}
    61             }
    62         }
    63     }
    64 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    caffe常用层: batchNorm层和scale层
    简述configure、pkg-config、pkg_config_path三者的关系
    python删除list中元素的三种方法
    Leetcode 872. Leaf-Similar Trees
    Leetcode 508. Most Frequent Subtree Sum
    Leetcode 572. Subtree of Another Tree
    Leetcode 894. All Possible Full Binary Trees
    Leetcode 814. Binary Tree Pruning
    Leetcode 557. Reverse Words in a String III
    python 多维list声明时的小问题
  • 原文地址:https://www.cnblogs.com/wls001/p/7191430.html
Copyright © 2011-2022 走看看