• LOJ-6277-数列分块入门1(分块)


    链接:

    https://loj.ac/problem/6277

    题意:

    给出一个长为 的数列,以及 个操作,操作涉及区间加法,单点查值。

    思路:

    线段树可以解决,用来学习分块.
    分块概念就是,将序列分为sqrt(n)块,每次区间操作在满足一个快时操作块,最多sqrt(n)块, 处于边界时,直接对边界暴力操作,复杂度最多sqrt(n).

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    //#include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    #include <string>
    #include <assert.h>
    #include <iomanip>
    #define MINF 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    const int MAXN = 5e4+10;
    
    int a[MAXN], Tag[MAXN];
    int Rank[MAXN];
    int n, part;
    
    void Update(int l, int r, int c)
    {
        for (int i = l;i <= min(r, Rank[l]*part);i++)
            a[i] += c;
        if (Rank[l] != Rank[r])
        {
            for (int i = (Rank[r]-1)*part+1;i <= r;i++)
                a[i] += c;
        }
        for (int i = Rank[l]+1;i <= Rank[r]-1;i++)
            Tag[i] += c;
    }
    
    int main()
    {
        scanf("%d", &n);
        part = sqrt(n);
        for (int i = 1;i <= n;i++)
            scanf("%d", &a[i]);
        for (int i = 1;i <= n;i++)
            Rank[i] = (i-1)/part+1;
        int op, l, r, c;
        for (int i = 1;i <= n;i++)
        {
            scanf("%d %d %d %d", &op, &l, &r, &c);
            if (op == 0)
                Update(l, r, c);
            else
                printf("%d
    ", a[r]+Tag[Rank[r]]);
        }
    
        return 0;
    }
    
  • 相关阅读:
    POJ 1789
    南华大学 复读机(并查集)
    C
    F
    POJ 1988 Cube Stacking
    并查集(一)
    把采集到的数据发送到一个Google Docs或者Google Form上 这个网站提供了参考和例子
    几种空气颗粒物和空气质量传感器
    整流桥
    STM32 中的CEC
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11394588.html
Copyright © 2020-2023  润新知