zoukankan      html  css  js  c++  java
  • BZOJ3155:Preprefix sum(线段树)

    Description

    Input

    第一行给出两个整数N,M。分别表示序列长度和操作个数
    接下来一行有N个数,即给定的序列a1,a2,....an
    接下来M行,每行对应一个操作,格式见题目描述

    Output

    对于每个询问操作,输出一行,表示所询问的SSi的值。

    Sample Input

    5 3
    1 2 3 4 5
    Query 5
    Modify 3 2
    Query 5

    Sample Output

    35
    32

    HINT

    1<=N,M<=100000,且在任意时刻0<=Ai<=100000

    Solution

    直接用线段树维护一次前缀和的数组$S$,然后修改后缀,查询前缀。注意常数。

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (100009)
     5 #define LL long long
     6 using namespace std;
     7 
     8 struct Sgt{LL val,add;}Segt[N<<2];
     9 int n,m,x,y;
    10 LL a[N],S[N];
    11 char opt[10];
    12 
    13 inline int read()
    14 {
    15     int x=0; char c=getchar();
    16     while (c<'0' || c>'9') c=getchar();
    17     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
    18     return x;
    19 }
    20 
    21 void Pushdown(int now,int l,int r)
    22 {
    23     if (Segt[now].add)
    24     {
    25         int mid=(l+r)>>1;
    26         Segt[now<<1].add+=Segt[now].add;
    27         Segt[now<<1|1].add+=Segt[now].add;
    28         Segt[now<<1].val+=Segt[now].add*(mid-l+1);
    29         Segt[now<<1|1].val+=Segt[now].add*(r-mid);
    30         Segt[now].add=0;
    31     }
    32 }
    33 
    34 void Update(int now,int l,int r,int l1,int r1,LL k)
    35 {
    36     if (l>r1|| r<l1) return;
    37     if (l1<=l && r<=r1)
    38     {
    39         Segt[now].add+=k;
    40         Segt[now].val+=(r-l+1)*k;
    41         return;
    42     }
    43     int mid=(l+r)>>1; Pushdown(now,l,r);
    44     Update(now<<1,l,mid,l1,r1,k);
    45     Update(now<<1|1,mid+1,r,l1,r1,k);
    46     Segt[now].val=Segt[now<<1].val+Segt[now<<1|1].val;
    47 }
    48 
    49 LL Query(int now,int l,int r,int l1,int r1)
    50 {
    51     if (l>r1|| r<l1) return 0;
    52     if (l1<=l && r<=r1) return Segt[now].val;
    53     int mid=(l+r)>>1; Pushdown(now,l,r);
    54     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
    55 }
    56 
    57 int main()
    58 {
    59     n=read(); m=read();
    60     for (int i=1; i<=n; ++i)
    61         a[i]=read(), S[i]=S[i-1]+a[i], Update(1,1,n,i,i,S[i]);
    62     while (m--)
    63     {
    64         scanf("%s",&opt); x=read();
    65         if (opt[0]=='Q') printf("%lld
    ",Query(1,1,n,1,x));
    66         else y=read(), Update(1,1,n,x,n,y-a[x]), a[x]=y;
    67     }
    68 }
  • 相关阅读:
    usb驱动开发6之端点描述符
    usb驱动开发5之总线设备与接口
    usb驱动开发4之总线设备驱动模型
    usb驱动开发3之先看core
    usb驱动开发2之代码地图
    usb驱动开发1之学习准备
    javascript限制上传文件大小
    google Chrome打开多个网站时等待可用的套接字,怎么加大连接数量提升速度
    sql将一张表的字段赋值给另一张表
    百度搜索网址参数的含义
  • 原文地址:https://www.cnblogs.com/refun/p/10361774.html
Copyright © 2011-2022 走看看