• COdeVS——T 1082 线段树练习 3 (分块练习)


     空间限制: 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

     1 #include <cstdio>
     2 #include <cmath>
     3 
     4 using namespace std;
     5 
     6 #define LL long long
     7 const int N(500);
     8 LL n,q,num[N*N],u,v,x,op;
     9 
    10 LL C,cnt,str[N],ove[N],bel[N*N],sum[N],tag[N];
    11 #define min(a,b) (a<b?a:b)
    12 #define max(a,b) (a>b?a:b)
    13 void Build()
    14 {
    15     C=sqrt(n);
    16     for(LL i=1;i<=n;i+=C)
    17     {
    18         str[++cnt]=i;
    19         ove[cnt]=min(n,i+C-1);
    20     }
    21     for(LL i=1;i<=cnt;i++)
    22         for(LL j=str[i];j<=ove[i];j++)
    23             bel[j]=i,sum[i]+=num[j];
    24 }
    25 void Update(LL u,LL v,LL x)
    26 {
    27     for(LL i=bel[u];i<=bel[v];i++)
    28         if(str[i]>=u&&ove[i]<=v) tag[i]+=x,sum[i]+=(ove[i]-str[i]+1)*x;
    29         else for(LL j=max(str[i],u);j<=min(ove[i],v);j++) num[j]+=x,sum[i]+=x;
    30 }
    31 LL Query(LL u,LL v)
    32 {
    33     LL ret=0;
    34     for(LL i=bel[u];i<=bel[v];i++)
    35         if(str[i]>=u&&ove[i]<=v) ret+=sum[i];
    36         else for(LL j=max(str[i],u);j<=min(ove[i],v);j++) ret+=num[j]+tag[i];
    37     return ret;
    38 }
    39 
    40 int main()
    41 {
    42     scanf("%lld",&n);
    43     for(LL i=1;i<=n;i++)
    44         scanf("%lld",num+i);
    45     Build();
    46     scanf("%lld",&q);
    47     for(;q--;)
    48     {
    49         scanf("%lld%lld%lld",&op,&u,&v);
    50         if(op==1)
    51         {
    52             scanf("%lld",&x);
    53             Update(u,v,x);
    54         }
    55         else printf("%lld
    ",Query(u,v));
    56     }
    57     return 0;
    58 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    poj3468一个简单的整数问题,我昨天一下午才写好的水代码。
    【虚幻】虚幻引擎小技巧
    ubuntu添加并设置屏幕分辨率
    ECDH秘钥协商算法原理
    ECC椭圆曲线算法2
    Neighbor Discovery Protocol
    IPv6 linklocal 地址的功能和原理
    ECC椭圆曲线算法3
    Linux下使用可视化的串口调试工具cutecom
    AES五种加密模式(CBC、ECB、CTR、OCF、CFB)
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7218055.html
Copyright © 2020-2023  润新知