zoukankan      html  css  js  c++  java
  • CodeForces-13E 分块

    给一个数组,有两种操作,一种是将a位数改成b,一种是判断从a点跳几次能跳出数组,每次跳从a到x【a】+a

    题解:用两个数组记录,每次点跳出下一个块 的次数,和跳到下一个块 的位置,用块来不断更新,查找的时候直接暴力跳每一个块,到最后一个块就挨个跳,

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=200000+10,maxn=60000+10,inf=0x3f3f3f3f;
    
    int n,m,block,num;
    int l[N],r[N],belong[N];
    int Next[N],cnt[N],a[N];
    void build()
    {
        block=(int)sqrt(n+0.5);
        num=n/block;
        if(n%block)num++;
        for(int i=1;i<=num;i++)
        {
            l[i]=(i-1)*block+1,r[i]=i*block;
        }
        r[num]=n;
        for(int i=1;i<=n;i++)
            belong[i]=(i-1)/block+1;
        for(int i=n;i>=1;i--)
        {
            int p=i,f=0;
            cnt[i]=1;
            while(belong[p+a[p]]==belong[p])
            {
                if(Next[p+a[p]])
                {
                    cnt[i]=cnt[p+a[p]]+1;
                    Next[i]=Next[p+a[p]];
                    f=1;
                    break;
                }
                cnt[i]++;
                p=p+a[p];
                if(p+a[p]>n)break;
            }
            if(!f)Next[i]=p+a[p];
        }
    }
    void update(int x,int y)
    {
        a[x]=y;
        for(int i=r[belong[x]];i>=l[belong[x]];i--)
        {
            int p=i,f=0;
            cnt[i]=1;
            while(belong[p+a[p]]==belong[p])
            {
                if(Next[p+a[p]])
                {
                    cnt[i]=cnt[p+a[p]]+1;
                    Next[i]=Next[p+a[p]];
                    f=1;
                    break;
                }
                cnt[i]++;
                p=p+a[p];
                if(p+a[p]>n)break;
            }
            if(!f)Next[i]=p+a[p];
        }
    }
    void query(int x)
    {
        int ans=1;
        while(x<=n)
        {
            if(Next[x]>n)
            {
                while(x+a[x]<=n)ans++,x=x+a[x];
                printf("%d ",x);
                break;
            }
            else
            {
                ans+=cnt[x];
                x=Next[x];
            }
        }
        printf("%d
    ",ans);
    }
    void debug()
    {
        for(int i=1;i<=n;i++)
            printf("%d %d
    ",Next[i],cnt[i]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        build();
       // debug();
        while(m--)
        {
            int x,y;
            scanf("%d",&x);
            if(x==0)
            {
                scanf("%d%d",&x,&y);
                update(x,y);
            }
            else
            {
                scanf("%d",&x);
                query(x);
            }
           // debug();
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code

    复杂度O(n*sqrt(n)

  • 相关阅读:
    Docker windows下安装,入门及注意事项,并搭建包含Nodejs的webapp
    360浏览器table中的td为空时td边框不显示的解决方法
    关于发布webservice提示The test form is only available for requests from the local machine
    CRM相关SQl手记
    页面右下角弹出的消息提示框
    MS CRM2011 js常用总结
    MVC razor 使用服务器控件
    常用正则表达式
    CRM 2011 常用对象
    人工智能AI-机器视觉CV-数据挖掘DM-机器学习ML-神经网络-[资料集合贴]
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7654528.html
Copyright © 2011-2022 走看看