zoukankan      html  css  js  c++  java
  • BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊:分块

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002

    题意:

      某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。

      游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。

      绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。

      为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

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

      n<=200000,m<=100000

    题解:

      分块。

      对于每个元素,维护两个值:

        nex[i]:表示从当前点第一次跳到下一个块的点的位置。

        stp[i]:表示跳出块要用的步数。

      update在一个块内暴力从后往前维护。

      query不断地跳区间就行了。

      两个操作都是单次O(sqrt(N))。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <math.h>
     5 #define MAX_N 200005
     6 
     7 using namespace std;
     8 
     9 int n,m;
    10 int len,cnt;
    11 int k[MAX_N];
    12 int pos[MAX_N];
    13 int nex[MAX_N];
    14 int stp[MAX_N];
    15 
    16 void read()
    17 {
    18     scanf("%d",&n);
    19     for(int i=1;i<=n;i++)
    20     {
    21         scanf("%d",&k[i]);
    22     }
    23 }
    24 
    25 void init_block()
    26 {
    27     len=sqrt(n)+1;
    28     cnt=ceil((double)n/(double)len);
    29     for(int i=1;i<=n;i++)
    30     {
    31         pos[i]=(i-1)/len+1;
    32     }
    33     for(int i=n;i>0;i--)
    34     {
    35         if(i+k[i]>n) nex[i]=0,stp[i]=1;
    36         else if(i+k[i]>pos[i]*len) nex[i]=i+k[i],stp[i]=1;
    37         else nex[i]=nex[i+k[i]],stp[i]=stp[i+k[i]]+1;
    38     }
    39 }
    40 
    41 void update(int x,int y)
    42 {
    43     k[x]=y;
    44     for(int i=min(pos[x]*len,n);i>(pos[x]-1)*len;i--)
    45     {
    46         if(i+k[i]>n) nex[i]=0,stp[i]=1;
    47         else if(i+k[i]>pos[i]*len) nex[i]=i+k[i],stp[i]=1;
    48         else nex[i]=nex[i+k[i]],stp[i]=stp[i+k[i]]+1;
    49     }
    50 }
    51 
    52 int query(int x)
    53 {
    54     int sum=0;
    55     while(x)
    56     {
    57         sum+=stp[x];
    58         x=nex[x];
    59     }
    60     return sum;
    61 }
    62 
    63 void work()
    64 {
    65     init_block();
    66     scanf("%d",&m);
    67     int opt,x,y;
    68     while(m--)
    69     {
    70         scanf("%d%d",&opt,&x);
    71         if(opt==1) printf("%d
    ",query(x+1));
    72         else
    73         {
    74             scanf("%d",&y);
    75             update(x+1,y);
    76         }
    77     }
    78 }
    79 
    80 int main()
    81 {
    82     read();
    83     work();
    84 }
  • 相关阅读:
    springmvc之异常处理DefaultHandlerExceptionResolver
    springmvc之异常处理ResponseStatusExceptionResolver
    springmvc之异常处理中ExceptionHanderExceptionResolver
    springmvc之多个拦截器方法执行的顺序
    springmvc之配置拦截器拦截相应的请求
    springmvc之自定义拦截器
    springmvc之文件上传
    springmvc之HttpMessageConverter<T>
    构建Java并发模型框架
    Java线程:线程的调度-守护线程——Java线程:线程的调度-合并——Java线程:新特征-障碍器——Java线程:大总结
  • 原文地址:https://www.cnblogs.com/Leohh/p/8021744.html
Copyright © 2011-2022 走看看