2018 徐州网络赛 H.Ryuji doesn't want to study 线段树

题意:有n本书和q次询问(n,q<=1e5),给定n本书的知识值ai。询问1:i,j,区间[i, j]的价值。询问2:a, b,将第a本书的知识值改为b。PS:[i, j]的价值计算,a[i]xL+a[i+1]x(L-1)+…+a[j-1]x2+a[j],L==j-i+1。

线段树维护三个东西
sum[]:单纯的知识值的和
ans[]:价值
len[]:区间长度

#include 
#include 

using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
ll sum[maxn<<2];
ll ans[maxn<<2];
ll len[maxn<<2];
int Len;

void pushup(int rt)
{
    ans[rt] = ans[rt<<1]+ans[rt<<1|1]+sum[rt<<1]*len[rt<<1|1];
    len[rt] = len[rt<<1]+len[rt<<1|1];
    sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}

void build(int l, int r, int rt)
{
    if(l == r)
    {
        scanf("%lld", &sum[rt]);
        len[rt] = 1;
        ans[rt] = sum[rt];
        return;
    }
    int mid = (l + r)>>1;
    build(l, mid, rt<<1);
    build(mid + 1, r, rt<<1|1);
    pushup(rt);
}

ll query(int L, int R, int l, int r, int rt)
{
    if(L <= l && r <= R)
    {
        int tmp = Len;
        Len -= len[rt];
        return ans[rt]+sum[rt]*(tmp-len[rt]);
    }
    int mid = (l + r)>>1;
    ll ret = 0;
    if(L <= mid)
        ret += query(L, R, l, mid, rt<<1);
    if(R >= mid + 1)
        ret += query(L, R, mid + 1, r, rt<<1|1);
    return ret;
}

void update(int p, ll th, int l, int r, int rt)
{
    if(l == r)
    {
        sum[rt] = th;
        ans[rt] = th;
        return;
    }
    int mid = (l + r)>>1;
    if(p <= mid)
        update(p, th, l, mid, rt<<1);
    else
        update(p, th, mid + 1, r, rt<<1|1);
    pushup(rt);
}

int main()
{
    int n, m;
    while(~scanf("%d %d", &n, &m))
    {
        build(1, n, 1);
        while(m--)
        {
            int op;
            scanf("%d", &op);
            if(op == 1)
            {
                int a, b;
                scanf("%d %d", &a, &b);
                Len = b-a+1;
                printf("%lld\n", query(a, b, 1, n, 1));
            }
            else
            {
                int a;
                ll b;
                scanf("%d %lld", &a, &b);
                update(a, b, 1, n, 1);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(线段树)