计算 + hihoCoder + 线段树

版权声明: https://blog.csdn.net/blackneed/article/details/81805501

计算

时间限制:4000ms

单点时限:1000ms

内存限制:256MB

描述

现在有一个有n个元素的数组a1, a2, ..., an。

记f(i, j) = ai * ai+1 * ... * aj。

初始时,a1 = a2 = ... = an = 0,每次我会修改一个ai的值,你需要实时反馈给我 ∑1 <= i <= j <= n f(i, j)的值 mod 10007。

输入

第一行包含两个数n(1<=n<=100000)和q(1<=q<=500000)。

接下来q行,每行包含两个数i, x,代表我把ai的值改为了x。

输出

分别输出对应的答案,一个答案占一行。

样例输入

5 5
1 1
2 1
3 1
4 1
5 1

样例输出

1
3
6
10
15

解题,可以看大佬传送门

想出来就很容易的线段树了,手打了一遍大佬的AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn = 100005;
#define MOD 10007
int sum[maxn<<2];
int ji[maxn<<2];
int pre[maxn<<2];
int suf[maxn<<2];
int n,q;
void PushUp(int re){
    ji[re] = ji[re<<1]*ji[re<<1|1]%MOD;
    sum[re] = (sum[re<<1] + sum[re<<1|1] + suf[re<<1]*pre[re<<1|1])%MOD;
    pre[re] = (pre[re<<1] + ji[re<<1]*pre[re<<1|1])%MOD;
    suf[re] = (suf[re<<1|1] + ji[re<<1|1]*suf[re<<1])%MOD;
}
void BuildTree(int re,int l,int r){
    sum[re] = 0;
    ji[re] = 0;
    pre[re] = 0;
    suf[re] = 0;
    if(l==r) return;
    int mid = (l+r)>>1;
    BuildTree(re<<1,l,mid);
    BuildTree(re<<1|1,mid+1,r);
}
void update(int rt, int l ,int r, int p, int x) {
    if(l == r && l == p) {
        sum[rt] = x % MOD;
        pre[rt] = x % MOD;
        suf[rt] = x % MOD;
        ji[rt] = x % MOD;
        return;
    }
    int mid = (l + r) >> 1;
    if(p <= mid) update(rt << 1, l, mid, p, x);
    else update(rt << 1 | 1, mid + 1, r, p, x);
    PushUp(rt);
}

int main() {
    scanf("%d %d", &n, &q);
    BuildTree(1, 1, n);
    for(int i = 0; i < q; i ++) {
        int p, x;
        scanf("%d %d", &p, &x);
        update(1, 1, n, p, x);
        printf("%d\n", sum[1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/blackneed/article/details/81805501