zoukankan      html  css  js  c++  java
  • [Codevs] 1082 线段树练习3

    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

    分析 Analysis

    分块!

    分块除了细节难调外没有什么问题,,,只要理解到位并且有自己的码风即可。

    更具体的分析:

    [Codevs] 1081 线段树练习 2 ----“分块!”

    代码 Code

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #define maxn 1000000
     5 using namespace std;
     6 
     7 long long block[maxn],size,sum[maxn],add[maxn],arr[maxn],n,q,swi;
     8 
     9 void modify(){
    10     long long a,b,c;
    11     scanf("%lld%lld%lld",&a,&b,&c);
    12     a--,b--;
    13     
    14     for(long long i = a;i <= min(block[a]*size-1,b);i++)
    15         arr[i] += c,sum[block[i]] += c;
    16     if(block[a] != block[b]){
    17         for(long long i = (block[b]-1)*size;i <= b;i++)
    18             arr[i] += c;
    19         sum[block[b]] += (b-(block[b]-1)*size+1)*c;
    20     }for(long long i = block[a]+1;i < block[b];i++)
    21         sum[i] += size*c,add[i] += c;
    22 }
    23 
    24 void query(){
    25     long long a,b;
    26     scanf("%lld%lld",&a,&b);
    27     a--,b--;
    28     long long ans = 0;
    29     
    30     for(long long i = a;i <= min(block[a]*size-1,b);i++)
    31         ans += arr[i]+add[block[i]];
    32     if(block[a] != block[b]){
    33         for(long long i = (block[b]-1)*size;i <= b;i++)
    34             ans += arr[i]+add[block[i]];
    35     }for(long long i = block[a]+1;i < block[b];i++)
    36         ans += sum[i];
    37         
    38     printf("%lld
    ",ans);
    39 }
    40 
    41 int main(){
    42     scanf("%lld",&n);
    43     size = (long long)sqrt(n)+1;
    44     for(long long i = 0;i < n;i++) block[i] = i/size+1;
    45     for(long long i = 0;i < n;i++) scanf("%lld",&arr[i]);
    46     for(long long i = 0;i < n;i++) sum[block[i]] += arr[i];
    47     
    48     scanf("%lld",&q);
    49     for(long long i = 0;i < q;i++){
    50         scanf("%lld",&swi);
    51         if(swi%2) modify();
    52         else query();
    53     }
    54     
    55     return 0;
    56 }
    分块!
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    将java库转换为.net库(转载)
    web sql设计器(连接)
    [SQLSERVER]SQL中的全文检索(转邹建)
    网络最经典命令行-网络安全工作者的必杀技
    无效的 CurrentPageIndex 值。它必须大于等于 0 且小于 PageCount。
    06毕业设计 VB导出Excel文档
    06毕业设计 VB导出word文档
    C# 交替显示项的DataGird,鼠标上移时转变颜色,退出后能恢复原来颜色
    js.offsetParent属性
    自动提醒IE6访客升级浏览器,
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7512398.html
Copyright © 2011-2022 走看看