zoukankan      html  css  js  c++  java
  • codevs 1082 线段树练习 3 --分块练习

    时间限制: 3 s
     空间限制: 128000 KB
     题目等级 : 大师 Master
    题目描述 Description

    给你N个数,有两种操作:


    1:给区间[a,b]的所有数增加X


    2:询问区间[a,b]的数的和。

    输入描述 Input Description

    第一行一个正整数n,接下来n行n个整数,

    再接下来一个正整数Q,每行表示操作的个数,

    如果第一个数是1,后接3个正整数,

    表示在区间[a,b]内每个数增加X,如果是2,

    表示操作2询问区间[a,b]的和是多少。

    pascal选手请不要使用readln读入

    输出描述 Output Description

    对于每个询问输出一行一个答案

    样例输入 Sample Input

    3

    1

    2

    3

    2

    1 2 3 2

    2 2 3

    样例输出 Sample Output

    9

    数据范围及提示 Data Size & Hint

    数据范围

    1<=n<=200000

    1<=q<=200000

     
    分块大法 此题用分块优于线段树
    #include <ctype.h>
    #include <cstdio>
    #include <cmath>
    #define N 500
    typedef long long LL;
    void read(LL &x)
    {
        x=0;bool f=0;char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-') f=1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        x=f?(~x)+1:x;
    }
    LL C,m,belong[N*N],cnt,tag[N],sum[N],beg[N],en[N],n,a[N*N]; 
    LL min(LL a,LL b) {return a>b?b:a;}
    LL max(LL a,LL b) {return a>b?a:b;} 
    void update(LL x,LL y,LL z)
    {
        for(LL i=belong[x];i<=belong[y];i++)
        {
            if(x<=beg[i]&&y>=en[i]) tag[i]+=z,sum[i]+=(en[i]-beg[i]+1)*z;
            else for(LL j=max(beg[i],x);j<=min(en[i],y);j++) a[j]+=z,sum[i]+=z;
        }
    }
    LL query(LL x,LL y)
    {
        LL ans=0;
        for(LL i=belong[x];i<=belong[y];i++)
        {
            if(x<=beg[i]&&y>=en[i]) ans+=sum[i];
            else for(LL j=max(beg[i],x);j<=min(en[i],y);j++) ans+=a[j]+tag[i];
        }
        return ans;
    }
    int main()
    {
        read(n);
        for(LL i=1;i<=n;i++) read(a[i]);
        C=sqrt(n);
        for(LL i=1;i<=n;i+=C)
        {
            beg[++cnt]=i;
            en[cnt]=min(i+C-1,n);
        }
        for(LL i=1;i<=cnt;i++)
        {
            for(LL j=beg[i];j<=en[i];j++) belong[j]=i,sum[i]+=a[j];
        }
        read(m);
        for(LL type,x,y,z;m--;)
        {
            read(type);
            read(x);
            read(y);
            if(type==1)
            {
                read(z);
                update(x,y,z);
            }
            else printf("%lld
    ",query(x,y));
        }
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    构建之法 阅读笔记01
    个人作业1 -数组
    进度一
    开课博客
    生活尝试
    人月神话3
    安卓开发工具
    人月神话 2
    Qt 的入门小程序
    提问的智慧 摘抄(How To Ask Questions The Smart Way)
  • 原文地址:https://www.cnblogs.com/ruojisun/p/6815833.html
Copyright © 2011-2022 走看看