zoukankan      html  css  js  c++  java
  • [HNOI2010] 弹飞绵羊 (分块)

    [HNOI2010] 弹飞绵羊

    题目描述

    某天,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。

    输出格式:

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

    输入输出样例

    输入样例#1:

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

    输出样例#1:

    2
    3

    说明

    对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    Solution

    分块...

    对于块中每个点,我们统计它什么时候会弹出块,以及弹出块后会弹到哪里

    对于修改(将v[x]修改为y),我们只需要暴力修改本块内x之前的信息,因为后面的我们不会影响,最坏时间复杂度(O(sqrt n))

    对于查询操作,我们每次都会跳一个块,最坏跳(sqrt n)个,所以最坏时间复杂度也是(O(sqrt n))

    然后就没了...

    Code

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define rg register
    #define lol long long
    #define Min(a,b) (a)<(b)?(a):(b)
    #define Max(a,b) (a)>(b)?(a):(b)
    #define in(i) (i=read())
    using namespace std;
    const int N=2e5+10;
    int read() {
        int ans=0,f=1; char i=getchar();
        while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
        while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
        return ans*f;
    }
    int n,m,blo;
    int v[N],pos[N],l[530],r[530],nex[N],sum[N];
    void change(int x,int y) {
        v[x]=y; int AQ=pos[x];
        for(int i=x;i>=l[AQ];i--)
            if(i+v[i]>r[AQ]) sum[i]=1,nex[i]=i+v[i];
            else sum[i]=sum[i+v[i]]+1,nex[i]=nex[i+v[i]];
    }
    
    int query(int x,int ans=0) {
        while(x<=n) {
            ans+=sum[x];
            x=nex[x];
        }return ans;
    }
    int main() {
        in(n); blo=sqrt(n);
        for(int i=1;i<=n;i++) in(v[i]),pos[i]=(i-1)/blo+1;
        for(int i=1;i<=pos[n];i++) {
            l[i]=r[i-1]+1,r[i]=Min(i*blo,n);
            for(int j=r[i];j>=l[i];j--)
                if(j+v[j]>r[i]) sum[j]=1,nex[j]=j+v[j];
                else sum[j]=sum[j+v[j]]+1,nex[j]=nex[j+v[j]];
        }
        in(m);
        while(m--) {
            int a,b,c; in(a),in(b),b++;
            if(a==1) printf("%d
    ",query(b));
            else in(c),change(b,c);
        }
    }
    
  • 相关阅读:
    django 项目需要注意的一些点
    VUE之路
    Oracle 表格碎片的查看方法
    RHEL 6.x or 7.x 使用分区绑定ASM 磁盘的方法
    RMAN 修复主库 nologging 操作导致物理备库的坏块
    Oracle 数据库19c 回退降级到 11.2.0.4 方案
    如何评估oracle 数据库rman全备和增量备份大小
    在将Oracle GI和DB升级到19c或降级到以前的版本之前需要应用的补丁 (Doc ID 2668071.1)
    Oracle 数据库坏块处理
    opatch auto 安装11.2.0.4.20190115 PSU遇到 OUI-67133: Execution of PRE script failed,with returen value 1 报错
  • 原文地址:https://www.cnblogs.com/real-l/p/9768940.html
Copyright © 2011-2022 走看看