• LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)


    内存限制:256 MiB时间限制:500 ms标准输入输出
    题目类型:传统评测方式:文本比较
    上传者: hzwer

    题目描述

    给出一个长为 nn 的数列,以及 nn 个操作,操作涉及区间加法,区间求和。

    输入格式

    第一行输入一个数字 nn。

    第二行输入 nn 个数字,第 ii 个数字为 a_iai,以空格隔开。

    接下来输入 nn 行询问,每行输入四个数字 mathrm{opt}opt、ll、rr、cc,以空格隔开。

    若 mathrm{opt} = 0opt=0,表示将位于 [l, r][l,r] 的之间的数字都加 cc。

    若 mathrm{opt} = 1opt=1,表示询问位于 [l, r][l,r] 的所有数字的和 mod (c+1)mod(c+1)。

    输出格式

    对于每次询问,输出一行一个数字表示答案。

    样例

    样例输入

    4
    1 2 2 3
    0 1 3 1
    1 1 4 4
    0 1 2 2
    1 1 2 4

    样例输出

    1
    4

    数据范围与提示

    对于 100\%100% 的数据,1 leq n leq 50000, -2^{31} leq mathrm{others}1n50000,231others、mathrm{ans} leq 2^{31}-1ans2311。

    代码;

     1 //#6280. 数列分块入门 4-区间加法,区间求和
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=5e4+10;
     6 
     7 int n,m,pos[maxn];
     8 ll a[maxn],b[maxn],tag[maxn];
     9 
    10 void update(int l,int r,ll c)
    11 {
    12     for(int i=l;i<=min(pos[l]*m,r);i++){
    13         a[i]+=c;
    14         b[pos[l]]+=c;
    15     }
    16     if(pos[l]!=pos[r]){
    17         for(int i=(pos[r]-1)*m+1;i<=r;i++){
    18             a[i]+=c;
    19             b[pos[r]]+=c;
    20         }
    21     }
    22     for(int i=pos[l]+1;i<pos[r];i++){
    23         tag[i]+=c;
    24     }
    25 }
    26 
    27 ll query(int l,int r)
    28 {
    29     ll ans=0;
    30     for(int i=l;i<=min(pos[l]*m,r);i++){
    31         ans+=a[i]+tag[pos[l]];
    32     }
    33     if(pos[l]!=pos[r]){
    34         for(int i=(pos[r]-1)*m+1;i<=r;i++){
    35             ans+=a[i]+tag[pos[r]];
    36         }
    37     }
    38     for(int i=pos[l]+1;i<pos[r];i++){
    39         ans+=b[i]+tag[i]*m;
    40     }
    41     return ans;
    42 }
    43 
    44 int main()
    45 {
    46     scanf("%d",&n);
    47     m=sqrt(n);
    48     for(int i=1;i<=n;i++){
    49         scanf("%d",&a[i]);
    50         b[i]=a[i];
    51         pos[i]=(i-1)/m+1;
    52     }
    53     for(int i=1;i<=m+1;i++){
    54         int cnt=0;
    55         for(int j=(i-1)*m+1;j<=min(i*m,n);j++){
    56             cnt+=a[j];
    57         }
    58         b[i]=cnt;
    59     }
    60     for(int i=1;i<=n;i++){
    61         int op,l,r;
    62         ll c;
    63         scanf("%d%d%d%lld",&op,&l,&r,&c);
    64         if(op==0){
    65             update(l,r,c);
    66         }
    67         else{
    68             printf("%lld
    ",query(l,r)%(c+1));
    69         }
    70     }
    71 }
    72 
    73 
    74 /*
    75 10
    76 1 3 4 2 5 7 11 3 5 1
    77 0 1 5 1
    78 1 1 7 2
    79 0 3 9 1
    80 1 4 8 7
    81 1 1 10 6
    82 1 3 5 3
    83 1 5 10 7
    84 1 6 10 6
    85 1 2 7 4
    86 1 2 7 5
    87 
    88 2
    89 3
    90 5
    91 1
    92 6
    93 3
    94 1
    95 5
    96 */
  • 相关阅读:
    PyQt5 控件学习(一个一个学习之QCommandLinkButton)
    多任务--线程
    PyQt5 控件学习(一个一个学习之QPushButton)
    PyQt5 控件学习(一个一个学习之QAbstractButton)
    再测我心中的事
    花了两天时间,整理了代码,封装了逻辑
    我现在发现,我写代码有严重的问题
    2014年8月2日0时13分22秒
    2014年8月2日15时13分4秒
    交警与货车司机
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10525669.html
Copyright © 2020-2023  润新知