• 分块算法&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());
            }
    }
  • 相关阅读:
    [心得]如何快速利用SqlMap做安全檢測
    [心得]群裡提問的流水序號產生方式
    STL中使用reverse_iterator时,如何正确使用erase函数
    西山居面试之旅
    LAMP兄弟连 视频教程集
    [译]理解Windows消息循环
    C++设计模式 -- 解析和实现
    winsock 收发广播包
    SqlServer sysobjects_table
    查询反模式
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8580262.html
Copyright © 2020-2023  润新知