ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lingzidong/article/details/82686299

题目:https://nanti.jisuanke.com/t/31460
题意:两个操作,操作一查询 i = 0 r l + 1 a [ l + i ] ( L i ) , L = r l + 1 ,操作二是单点修改
单点修改好说,我们先来想第一个操作,直接更新的话肯定会超时,我们不妨开两个树状数组,然后分别更新(n - i +1)*a[i], 和a[i] 的前缀和,最后拆卸你的时候就变成 a [ i ] ( n i 1 ) ( n r ) a [ i ]
至于怎么推出来的,本人是画格子画出来的……

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e5 + 5;
ll bit1[MAXN],bit2[MAXN],a[MAXN];
int n,q;
int lowbit(int x)
{
    return x  & (-x);
}
void update(int x,ll val,ll b[])
{
    while(x <= n)
    {
        b[x] += val;
        x += lowbit(x);
    }
}
ll query(int x,ll b[])
{
    ll res = 0;
    while(x)
    {
        res += b[x];
        x -= lowbit(x);
    }
    return res;
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i = 1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        update(i,a[i],bit1);
        update(i,(n - i + 1)*a[i],bit2);
    }
    while(q--)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(x == 1)
        {
            ll ans1 = query(z,bit2) - query(y-1,bit2);
            ll ans2 = (n - z)*(query(z,bit1) - query(y-1,bit1));
            //cout<<ans1<<' '<<ans2<<endl;
            printf("%lld\n",ans1 - ans2);
        }
        else
        {
            ll val = z - a[y];
            update(y,val,bit1);
            update(y,val*(n - y +1),bit2);
            a[y] = z;
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/lingzidong/article/details/82686299