2018ICPC徐州站网络赛 Ryuji doesn't want to study 思维+前缀和+树状数组

做这道题让我对线段树和树状数组有了更深的理解。。

主要是维护两个前缀和,一个a[i],一个(n-i+1)*a[i],最后结果减一下。剩下就是注意一些树状数组的操作更改了。

附上通过代码:

#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long

const int MAX=112345;
ll aa[MAX],s1[MAX],s2[MAX];
ll t1[MAX],t2[MAX];
ll n,q,ans;

ll lowbit(ll i)
{
    return i&(-i);
}
void update1(ll i,ll k)
{
    while(i<=n)
    {
        t1[i]+=k;
        i+=lowbit(i);
    }
}
ll query1(ll i)
{
    ll sum=0;
    while(i>0)
    {
        sum+=t1[i];
        i-=lowbit(i);
    }
    return sum;
}
void update2(ll i,ll k)
{
    while(i<=n)
    {
        t2[i]+=k;
        i+=lowbit(i);
    }
}
ll query2(ll i)
{
    ll sum=0;
    while(i>0)
    {
        sum+=t2[i];
        i-=lowbit(i);
    }
    return sum;
}

int main()
{
    while(scanf("%lld%lld",&n,&q)==2)
    {
        memset(s1,0,sizeof(s1));
        memset(s2,0,sizeof(s2));
        memset(t1,0,sizeof(t1));
        memset(t2,0,sizeof(t2));
        memset(aa,0,sizeof(aa));
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&aa[i]);
            s1[i]=s1[i-1]+aa[i];
            s2[i]=(n-i+1)*aa[i]+s2[i-1];
        }
        /*for(int i=1;i<=n;i++)
            cout<

 

你可能感兴趣的:(算法-线段树,树状数组)