• 分块算法&BZOJ2002


    题目传送门

    第一次接触分块......

    分块查找是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。

    分块修改理论复杂度为O(N/M),M为块的大小,有基本不等式得M=Sqrt(N)时较优。

    分块将原数组分为M块,对M块的信息进行维护。

    这道题每个点记录一个它跳到下一个不是同一块的点是哪个点及需要几步跳到那个点。

    code:

    /**************************************************************
        Problem: 2002
        User: yekehe
        Language: C++
        Result: Accepted
        Time:1648 ms
        Memory:3956 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <cmath>
    using namespace std;
     
    int read()
    {
        char c;while(c=getchar(),c<'0'||c>'9');
        int x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';
        return x;
    }
     
    const int MAXN=200005;
    int N,M,Q,a[MAXN];
    int belong[MAXN],nxt[MAXN],J[MAXN];
     
    int Query(int x)
    {
        int tot=0;
            while(x<=N){
                tot+=J[x];
                x=nxt[x];
            }
        return tot;
    }
     
    void Change(int x,int y)
    {
        int l=(belong[x]-1)*M+1,r=belong[x]*M;
        a[x]=y;
            for(int i=x;i>=l;i--){
                if(i+a[i]>r)nxt[i]=i+a[i],J[i]=1;
                else nxt[i]=nxt[i+a[i]],J[i]=J[i+a[i]]+1;
            }
        return ;
    }
     
    int main()
    {
        N=read();M=sqrt(N);
        if(M*M<N)M++;
        register int i,j;
            for(i=1;i<=N;i++)a[i]=read();
        j=1;
            for(i=1;i<=M;i++)
                for(;j<=i*M&&j<=N;j++)
                    belong[j]=i;
            for(i=1;i<=N;i++){
                int Ks=0;
                    for(j=i;j<=N&&belong[j]==belong[i];j+=a[j])Ks++;
                nxt[i]=(j>N?N+1:j);
                J[i]=Ks;
            }
        Q=read();
            while(Q--){
                int o=read(),x=read();
                if(o==1)printf("%d
    ",Query(x+1));
                else Change(x+1,read());
            }
    }
  • 相关阅读:
    大道至简观后感
    冲刺第二天
    梦断代码阅读笔记 02
    冲刺第一天
    第十周学习进度
    个人冲刺第一阶段个人任务--界面
    软工第二周个人作业
    软件工程开课博客(自我介绍)
    梦断代码阅读笔记01
    第二周学习进度报告
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8580262.html
Copyright © 2020-2023  润新知