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

    刷刷水题... 

    前缀和的前缀和...显然树状数组可以写...然而我不会, 只能写线段树了 

    把改变成加, 然后线段树维护前缀和, 某点p加, 会影响前缀和pre(x)(p≤x≤n), 对[p, n]这段区间加即可, 然后query就求[1, p]的和即可 

    ---------------------------------------------------------------------------------

    #include<bits/stdc++.h>
     
    using namespace std;
     
    typedef long long ll;
     
    const int maxn = 100009;
     
    int L, R, v, seq[maxn], N;
    ll cnt[maxn];
     
    struct Node {
    Node *l, *r;
    ll add, sum;
    Node() {
    add = 0;
    }
    inline void pushdown() {
    if(add) {
    l->add += add;
    r->add += add;
    add = 0;
    }
    }
    inline void update(int len) {
    if(l) sum = l->sum + r->sum;
    sum += add * len;
    if(!l) add = 0;
    }
    } pool[maxn << 1], *pt = pool, *root;
     
    void build(Node* t, int l, int r) {
    if(l == r) {
    t->sum = cnt[l];
    } else {
    int m = (l + r) >> 1;
    build(t->l = pt++, l, m);
    build(t->r = pt++, m + 1, r);
    t->update(r - l + 1);
    }
    }
     
    void modify(Node* t, int l, int r) {
    if(L <= l && r <= R) {
    t->add += v;
    } else {
    t->pushdown();
    int m = (l + r) >> 1;
    L <= m ? modify(t->l, l, m) : t->l->update(m - l + 1);
    m < R ? modify(t->r, m + 1, r) : t->r->update(r - m);
    }
    t->update(r - l + 1);
    }
     
    ll query(Node* t, int l, int r) {
    if(L <= l && r <= R) return t->sum;
    int m = (l + r) >> 1;
    t->pushdown();
    t->l->update(m - l + 1); t->r->update(r - m);
    return (L <= m ? query(t->l, l, m) : 0) + (m < R ? query(t->r, m + 1, r) : 0);
    }
     
    int main() {
    int m; scanf("%d%d", &N, &m);
    for(int i = 1; i <= N; i++) scanf("%d", seq + i);
    cnt[0] = 0;
    for(int i = 1; i <= N; i++) cnt[i] += cnt[i - 1] + seq[i];
    build(root = pt++, 1, N);
    while(m--) {
    char s[10]; scanf("%s", s);
    if(s[0] == 'M') {
    int p, v; scanf("%d%d", &p, &v);
    ::v = v - seq[p];
    seq[p] = v;
    L = p; R = N;
    modify(root, 1, N);
    } else {
    L = 1;
      scanf("%d", &R);
    printf("%lld ", query(root, 1, N));
    }
    }
    return 0;
    }

    --------------------------------------------------------------------------------- 

    3155: Preprefix sum

    Time Limit: 1 Sec  Memory Limit: 512 MB
    Submit: 765  Solved: 341
    [Submit][Status][Discuss]

    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

    Source

  • 相关阅读:
    【转载】Hadoop 文件副本存放的位置策略
    【原创】Hadoop 常用命令集锦
    【转载】centos6.2下安装星际译王stardict3.0
    【转载】hadoop之failed task任务和killed task任务
    【原创】linux 下远程连接windows桌面
    【原创】Hadoop配置详解
    【原创】Pig 0.10.0 piggybank 如何编译
    【转载】关于hadoop的dfs.replication
    【原创】centos 安装 thrift 0.8
    【原创】ASP.NET常见问题集锦
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4793033.html
Copyright © 2011-2022 走看看