• HNOI2010 弹飞绵羊


    传送门

    这道题听说是LCT的裸题……但是我只会分块。

    分块的复杂度肯定是能过的orz,抗下200000很有信心。

    我们还是老套路分成sqrt(n)块,之后我们统计两个值,一个是当前点弹几次会被弹出块,第二个是当前点弹出块以后到了哪(这两个都是要倒着枚举的,O(n))

    之后,对于查询,我们直接暴力跳就行了,复杂度为O(sqrt(n)),而对于修改的话,修改一个块内的某一个值对前后块都没有任何影响,只要暴力把这个块内所有值全部重构即可,复杂度为O(sqrt(n)),总复杂度为O(nsqrt(n))。

    简直是暴力到极限了……反正我真的是被刷新了三观orz。

    代码也很简洁,看一下代码。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    using namespace std;
    typedef long long ll;
    const int M = 200005;
    const int N = 10000005;
     
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >='0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    int n,m,B,cnt,ans,a[M],l[M],r[M],step[M],to[M],blo[M],g = 1,op,x,y;
    
    int main()
    {
        n = read();
        rep(i,1,n) a[i] = read();
        B = (int)sqrt(n),cnt = (n % B) ? n / B + 1 : n / B;
        rep(i,1,cnt) l[i] = r[i-1] + 1,r[i] = l[i] + B - 1;r[cnt] = n;
        rep(i,1,n)
        {
        blo[i] = g;
        if(i == r[g]) g++;
        if(g > cnt) break;
        }
        //rep(i,1,n) printf("#%d ",blo[i]);enter;
        per(i,n,1)
        {
        to[i] = i + a[i];
        if(to[i] > r[blo[i]]) step[i] = 1;
        else step[i] = step[to[i]] + 1,to[i] = to[to[i]];
        }
        m = read();
        while(m--)
        {
        op = read();
        if(op == 1)
        {
            x = read() + 1;
            int ans = 0;
            while(x <= n) ans += step[x],x = to[x];
            printf("%d
    ",ans);
        }
        else
        {
            x = read() + 1,y = read(),a[x] = y;
            per(i,r[blo[x]],l[blo[x]])
            {
            to[i] = i + a[i];
            if(to[i] > r[blo[i]]) step[i] = 1;
            else step[i] = step[to[i]] + 1,to[i] = to[to[i]];
            }
        }
        //rep(i,1,n) printf("%d ",step[i]);enter;
        //rep(i,1,n) printf("%d ",to[i]);enter;
        }
        return 0;
    }
  • 相关阅读:
    jQuery选择器汇总
    jQuery源码分析系列:总体架构
    jQuery源码分析系列:队列操作
    jQuery源码分析系列:事件
    jQuery源码分析系列:数据缓存
    jQuery源码分析系列:Deferred延迟队列
    Redis基本数据类型与内部存储结构
    oracle 学习笔记1
    设计模式学习1
    注册DEV控件
  • 原文地址:https://www.cnblogs.com/captain1/p/9823584.html
Copyright © 2020-2023  润新知