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

    给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,单点查值。
    Input
    第一行输入一个数字 n。
    第二行输入 n 个数字,第 i 个数字为 ai,以空格隔开。
    接下来输入 n行询问,每行输入四个数字 opt、l、r、c,以空格隔开。
    若 opt=0,表示将位于 [l,r]的之间的数字都加 c。
    若 opt=1,表示询问 ar 的值(l 和 c 忽略)。
    1≤n≤50000,-2^31 ≤others、ans≤2^31-1
    Output
    对于每次询问,输出一行一个数字表示答案。
    Sample Input
    4
    1 2 2 3
    0 1 3 1
    1 0 1 0
    0 1 2 2
    1 0 2 0
    Sample Output
    2
    5

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=5e4+5;
    int n,blo;
    int v[N],bl[N],tag[N];
    void add(int a,int b,int c)
    {
        for(int i=a;i<=min(bl[a]*blo,b);i++)
    	//从a开始的一段元素加上c,直到这一整块结束
            v[i]+=c;
        if(bl[a]!=bl[b])//如果a,b不在一个段中的话 
            for(int i=(bl[b]-1)*blo+1;i<=b;i++)
    		//以b为结束的一段元素加上c 
                v[i]+=c;
        for(int i=bl[a]+1;i<=bl[b]-1;i++)
    	//整段整段元素加上一个lazy标记 
            tag[i]+=c;
    }
    int main() {
        scanf("%d",&n);
        blo=sqrt(n);//块大小 
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&v[i]);
            bl[i]=(i-1)/blo+1;//第i个数字属于哪个块 
            //[1..10]是第1块
            //[11.20]是第2块
        }
        for(int i=1; i<=n; i++) 
        {
            int f,a,b,c;
            scanf("%d%d%d%d",&f,&a,&b,&c);
            if(f==0)  //表示将位于 [l,r]的之间的数字都加 c 
                add(a,b,c);
            else
                 printf("%d
    ",v[b]+tag[bl[b]]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    寻找水王
    学习进度条(第十一周)
    学习进度条(第十周)
    学习进度条(第九周)
    团队项目:个人工作总结10
    团队项目:个人工作总结09
    团队项目:个人工作总结08
    深度学习之--深度置信网络DBN
    神经网络学习之----受限玻尔兹曼机RBM(代码实现)
    神经网络学习之----受限玻尔兹曼机RBM
  • 原文地址:https://www.cnblogs.com/cutemush/p/12793212.html
Copyright © 2011-2022 走看看