zoukankan      html  css  js  c++  java
  • LibreOJ 6277. 数列分块入门 1

    题目链接:https://loj.ac/problem/6277

    参考博客:https://www.cnblogs.com/stxy-ferryman/p/8547731.html

    两个操作,区间增加和单点查询。

    思路:将整个数组按照block(block=sqrt(n))分成许多小块,lump[i]表示点i所在的块,tag[i]表示编号为i的块的增加值,如果是进行区间增加操作,我们一般可以把区间[l,r]分成三个部分,左边不完整的区间(只含有某块中的部分点),中间完整的区间(含有一些块的所有点),右边不完整的区间。这样对于左右的不完整区间,他们的点的数量是比较少的,我们可以进行暴力更新,对于中间的完整区间,一般来说他们的点比较多,我们就用标记数组tag[i]来记录第i块里增加的数,从而避免对太多的点进行单点更新。在单点查询时,某个点的值就是本身数组的值加上这个点所在的块的标记数组值(a[r]+tag[lump[r])。

    点i所在的块是lump[i]=(i-1)/block+1,表示lump[i]=i/block+1。

    假设现在n=9,那么block=sqrt(9)=3。

    对1到9之间的点分块,在i=3时,错误:3/3+1=2,3就在第二组  ,但是这是不对的,按理说3应该在第一组,怎么办,把3减1....

    代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<cstdio>
    #include<string>
    #include<deque> 
    using namespace std;
    typedef long long LL;
    #define eps 1e-8
    #define INF 0x3f3f3f3f
    #define maxn 50005
    /*struct point{
        int u,w;
    };
    bool operator <(const point &s1,const point &s2)
    {
        if(s1.w!=s2.w)
        return s1.w>s2.w;
        else
        return s1.u>s2.u;
    }*/
    int tag[maxn],a[maxn],lump[maxn];
    int n,m,k,t,block;
    void add(int l,int r,int c)//这里注意要把各个块的边界写正确 
    {
        for(int i=l;i<=min(lump[l]*block,r);i++)//左边的不完整的块  暴力更新每个点 
        a[i]+=c;
        if(lump[l]!=lump[r])//左边界和右边界不在一个块里面 
        {
            for(int i=(lump[r]-1)*block+1;i<=r;i++)//右边的不完整的块  暴力更新 
            a[i]+=c;
        }
        for(int i=lump[l]+1;i<=lump[r]-1;i++)//中间的完整的块的标记数组  增加值 
        tag[i]+=c;
    }
    int main()
    {
        scanf("%d",&n);
        block=sqrt(n);
        fill(tag,tag+maxn-1,0);
        for(int i=1;i<=n;i++)//给每个点分块 
        lump[i]=(i-1)/block+1;
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        int op,l,r,c;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&op,&l,&r,&c);
            if(op==0)
            add(l,r,c);
            else
            printf("%d
    ",a[r]+tag[lump[r]]);
        }
        return 0;
    }
  • 相关阅读:
    Mysql安装
    Python的内存管理机制
    Ansible模块
    Redis持久化
    Linux——ansible(1)
    Flask
    Flask入门
    ajax处理回调函数,用ajax向后台发送数据
    数字类型钱币转换为大写
    ligerui多选动态下拉框
  • 原文地址:https://www.cnblogs.com/6262369sss/p/9734584.html
Copyright © 2011-2022 走看看