hiho1116 - 数据结构 线段树(区间合并)

题目链接

现在有一个有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。

/*******************************************************/

记两个数的区间【a,b】

[a,b].sum = a+b+a*b;

[a,b].prefix = a+a*b;

[a,b].suffix = b+a*b;

[a,b].product = a*b;

 

当合并区间【a,b】和【c,d】时

有[a,b,c,d].sum = [a,b].sum+[c,d].sum+[a,b].suffix*[c,d].prefix;

[a,b,c,d].product = a*b*c*d = [a,b].product*[c,d].product;

.product的存在是为了维护prefix和suffix,因为:

[a,b,c,d].prefix = [a,b].prefix + [a,b].product*[c,d].prefix;

[a,b,c,d].suffix = [c,d].suffix + [c,d].product*[a,b].suffix;

#include <cstdio>
#include <cstring>
const int N = 100100;
const int MOD = 10007;
struct NODE{
    int l,r;
    int sum;
    int prefix,suffix,product;
    NODE(){
        sum = prefix = suffix = product = 0;
    }
    int MID(){ return (l+r)>>1;    }    
};
NODE segtree[N*3];
void build(int id,int l,int r){
    segtree[id].l = l;
    segtree[id].r = r;
    if(l==r) return ;
    int mid = (l+r)>>1;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
}
void modify(int id,int pos,int value){
    if((segtree[id].l==segtree[id].r)&&(segtree[id].l==pos)){
        segtree[id].sum = segtree[id].prefix = segtree[id].suffix = segtree[id].product = (value)%MOD;
        return ;
    }
    int mid = segtree[id].MID();
    if(pos<=mid) modify(id*2,pos,value);
    else modify(id*2+1,pos,value);
    
    segtree[id].sum = ((segtree[id*2].sum+segtree[id*2+1].sum)+(segtree[id*2].suffix*segtree[id*2+1].prefix)%MOD)%MOD;
    segtree[id].prefix = (segtree[id*2].prefix+(segtree[id*2].product*segtree[id*2+1].prefix)%MOD)%MOD;
    segtree[id].suffix = (segtree[id*2+1].suffix+(segtree[id*2+1].product*segtree[id*2].suffix)%MOD)%MOD;
    segtree[id].product = (segtree[id*2].product*segtree[id*2+1].product)%MOD;
}
int main(){
    int n,q,a,b;
    scanf("%d%d",&n,&q);
    build(1,1,n);
    while(q--){
        scanf("%d%d",&a,&b);
        modify(1,a,b);
        printf("%d\n",segtree[1].sum);
    }
    return 0;
}

 

posted @ 2017-05-10 10:20  redips  阅读(234)  评论(0编辑  收藏  举报