• 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 }
  • 相关阅读:
    2012 Multi-University Training Contest 8
    uva 11354最小生成树瓶颈路(lca算法实现)(rmq在多校二中有一道题)
    POJ 3164最小树形图
    uva11865 二分+最小树形图(朱刘算法)
    LA 5717枚举+最小生成树回路性质
    2014/3/9 长沙多校(第二次)
    zoj3759(待解决+算法木有问题+but需要java大数)
    ztr loves lucky numbers--hdu5676(DFS)
    C. Nearest vectors--cf598C(极角排序)
    D. Spongebob and Squares--cf599D(数学)
  • 原文地址:https://www.cnblogs.com/refun/p/10361774.html
Copyright © 2020-2023  润新知