zoukankan      html  css  js  c++  java
  • CodeForces 13E. Holes 分块处理

        正解是动态树,太难了,仅仅好分块处理水之。看了看status大概慢了一倍之多。。
        分块算法大体就是在找一个折衷点,使得查询和改动的时间复杂度都不算太高,均为o(sqrt(n)),所以总的时间复杂度为o(m*sqrt(n))。
        分块的大体思想就是将整段区间分成sqrt(n),每次改动影响所在段内的sqrt(n)个点。每次查询遍历sqrt(n)段,然后搞出一些事情。
        对于此题,首先说明几个数组的含义:
        cnt[i]的意义为从i点開始跳出其所在段所须要的步数。
        goal[i]的意义为从i点開始所经历的最后一个点。
        jmp[i]的意义为从i点開始跳出所在段之后第一个到达点。
        明确了这几个意义之后看代码就好了,文字太无力。

        

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <ctime>
    #include <iomanip>
    
    #pragma comment(linker, "/STACK:1024000000");
    #define EPS (1e-6)
    #define LL long long
    #define ULL unsigned long long
    #define _LL __int64
    #define INF 0x3f3f3f3f
    #define Mod 1000000007
    
    using namespace std;
    
    const int MAXN = 100010,BLOCK = sqrt(100010);
    
    int jmp[MAXN],cnt[MAXN],goal[MAXN],val[MAXN];
    
    void Updata(int x,int y,int n)
    {
        if(y > n)
        {
            jmp[x] = MAXN;
            cnt[x] = 1;
            goal[x] = x;
        }
        else if(x/BLOCK*BLOCK == y/BLOCK*BLOCK)
        {
            jmp[x] = jmp[y];
            cnt[x] = cnt[y]+1;
            goal[x] = goal[y];
        }
        else
        {
            jmp[x] = y;
            cnt[x] = 1;
            goal[x] = y;
        }
    }
    
    void Cal(int x)
    {
        int ans = 0,f;
    
        while(x != MAXN)
        {
            f = goal[x];
            ans += cnt[x];
            x = jmp[x];
        }
    
        printf("%d %d
    ",f,ans);
    
    }
    
    int main()
    {
        int i,j,u,v,n,m,ord,L;
    
        scanf("%d %d",&n,&m);
    
        for(i = 1;i <= n; ++i)
            scanf("%d",&val[i]);
    
        for(i = n;i >= 1; --i)
            Updata(i,i+val[i],n);
    
        while(m--)
        {
            scanf("%d",&ord);
    
            if(ord)
            {
                scanf("%d",&u);
                Cal(u);
            }
            else
            {
                scanf("%d %d",&u,&v);
                val[u] = v;
                L = u/BLOCK*BLOCK;
                for(i = u;i >= L; --i)
                    Updata(i,i+val[i],n);
            }
        }
    
        return 0;
    }
    
    
    
    
    
    
    
    
    
    
    


  • 相关阅读:
    python基础
    HTTP长连接和短连接及应用情景
    HTTP和HTTPS的区别
    python---重建二叉树
    python---替换空格
    python---二维数组的查找
    python---从尾到头打印链表
    python---反转链表
    python---两个栈实现一个队列
    python---二分查找的实现
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5128253.html
Copyright © 2011-2022 走看看