• HYSBZ_2002_分块


    http://www.lydsy.com/JudgeOnline/problem.php?id=2002

    分块基础题,初次接触,很巧妙。

    OJ好像挂了,没法提交。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int a[200005],cnt[200005],next[200005],l[1000],r[1000],belong[200005],n,m;
    
    void build()
    {
        int block = sqrt(n);
        int 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 temp = i+a[i];
            if(temp > n)
            {
                cnt[i] = 1;
                next[i] = -1;
            }
            else if(belong[i] == belong[temp])
            {
                cnt[i] = cnt[temp]+1;
                next[i] = next[temp];
            }
            else
            {
                cnt[i] = 1;
                next[i] = temp;
            }
        }
    }
    
    int getsum(int x)
    {
        int ans = cnt[x];
        while(next[x] > 0)
        {
            x = next[x];
            ans += cnt[x];
        }
        return ans;
    }
    
    void update(int x,int y)
    {
        a[x] = y;
        for(int i = x;i >= l[belong[x]];i--)
        {
            int temp = i+a[i];
            if(temp > n)
            {
                cnt[i] = 1;
                next[i] = -1;
            }
            else if(belong[i] == belong[temp])
            {
                cnt[i] = cnt[temp]+1;
                next[i] = next[temp];
            }
            else
            {
                cnt[i] = 1;
                next[i] = temp;
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);
        build();
        scanf("%d",&m);
        while(m--)
        {
            int i,j,k;
            scanf("%d%d",&i,&j);
            if(i == 1)  printf("%d
    ",getsum(j+1));
            else
            {
                scanf("%d",&k);
                update(j+1,k);
            }
        }
        return 0;
    }
  • 相关阅读:
    设为首页 和 收藏本页
    软件开发:需求分析的20条法则
    常用的50条网站推广方法
    IT人士在离职时可以做的14件事情
    需求文档的编写
    无法清除DNS缓存
    输入法没有了 输入法不见了
    CMS
    用户输入的防注入总结 简介和第一步
    winmail无法给新浪发送邮件
  • 原文地址:https://www.cnblogs.com/zhurb/p/5933091.html
Copyright © 2020-2023  润新知