zoukankan      html  css  js  c++  java
  • 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 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7218055.html
Copyright © 2011-2022 走看看