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

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2002

    2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 14824  Solved: 7515
    [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

    题意概括:略

    解题思路:

    在线的查询,神奇暴力算法分块!

    记录每个点跳到下一分块的步数和每个点跳到下一分块的位置

    AC code:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cmath>
     5 #include <cstring>
     6 #define ll long long int
     7 #define INF 0x3f3f3f3f
     8 using namespace std;
     9 const int MAXN = 2e5+10;
    10 inline ll read()
    11 {
    12     ll x = 0, f = 1; char ch = getchar();
    13     while(ch > '9' || ch < '0') {if(ch == '-')f = -1; ch = getchar();}
    14     while(ch >= '0' && ch <= '9'){x=x*10+ch-'0'; ch = getchar();}
    15     return x*f;
    16 }
    17 int N, M;
    18 int block, cnt; ///分块的大小,分块的数量
    19 int pt[MAXN], st[MAXN]; ///记录跳打下一个分块的位置 记录跳到下一个分块的步数
    20 int K[MAXN];
    21 int belong[MAXN];   ///记录当前的数属于第几个分块
    22 int l[MAXN], r[MAXN];  ///记录每个分块的左右边界
    23 inline int cal(int x)
    24 {
    25     int temp = 0;
    26     while(1){
    27         temp+=st[x];
    28         if(!pt[x]) break;  ///飞出去了
    29         x = pt[x];         ///跳到下一个点
    30     }
    31     return temp;
    32 }
    33 int main()
    34 {
    35     N = read();
    36     block = sqrt(N);
    37     for(int i = 1; i <= N; i++){
    38         K[i] = read();
    39     }
    40     if(N%block) cnt = N/block+1;
    41     else cnt = N/block;
    42 
    43     for(int i = 1; i <= cnt; i++){
    44         l[i] = (i-1)*block+1;    ///相当于退回前一个的右端点+1
    45         r[i] = i*block;
    46     }
    47     r[cnt] = N;
    48 
    49     for(int i = 1; i <= N; i++){
    50         belong[i] = (i-1)/block+1;
    51     }
    52 
    53     for(int i = N; i > 0; i--){
    54         if(i+K[i] > N) st[i] = 1;   ///飞出去了
    55         else if(belong[i] == belong[i+K[i]]){    ///还没跳出当前分块
    56             st[i] = st[i+K[i]]+1; pt[i] = pt[i+K[i]];
    57         }
    58         else st[i] = 1, pt[i] = i+K[i]; ///跳到下一个分块
    59     }
    60     M = read();
    61     int x, y, command;
    62     for(int i = 1; i <= M; i++){
    63         command = read(), x = read();
    64         x++;
    65         if(command == 1) printf("%d
    ", cal(x));
    66         else{
    67             y = read();
    68             K[x] = y;
    69             for(int i = x; i >= l[belong[x]]; i--)
    70                 if(belong[i] == belong[i+K[i]]){    ///还没跳出当前分块
    71                     st[i] = st[i+K[i]]+1; pt[i] = pt[i+K[i]];
    72                 }
    73             else st[i] = 1, pt[i] = i+K[i]; ///跳到下一个分块
    74         }
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    解决ftp的pasv模式下iptables设置问题
    linux修改运行中的脚本
    shell脚本——列出质数
    转载:tomcat设置https的两种方式
    Centos缺少ifconfig命令
    转载:MySQL 数据库设计总结
    转载:HTML5视频推流方案
    转载:Linux五种方案快速恢复你的系统
    转载:HT可视化案例
    转载:21种JavaScript设计模式最新记录(含图和示例)
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9566884.html
Copyright © 2011-2022 走看看