题意:
给出数组a,有询问更新操作,更新是单点更新pos, x,更新a[pos]=x,询问是问l,r区间内的sweet值,定义是:
(-1)i-lAi × (i - l + 1)
比如:
- [3, 1, 6] is 3 × 1 - 1 × 2 + 6 × 3 = 19
- [40, 30, 20, 10] is 40 × 1 - 30 × 2 + 20 × 3 - 10 × 4 = 0
- [2, 100] is 2 × 1 - 100 × 2 = -198
解题思路:
维护两个树状数组,一个s1记录a[1]-a[2]+a[3]...+-1^(i+1)(a[i]),
一个s2记录a[i]-2*a[i]+3*a[3]+...+-1(^(i+1)*i*a[i],
询问l,r区间合的时候, -1^(l+1)*(s2[r]-s2[l-1]-(l-1)*(s1[r]-s1[l-1]))就是答案了
代码:
#include <bits/stdc++.h>
#define ps push_back
#define LL long long
using namespace std;
const int maxn=2e5+5;
long long s1[maxn],s2[maxn], a[maxn];
int n, m;
int lowbit(int x)
{
return x&(-x);
}
void add1(int pos, LL x)
{
for(int i=pos; i<maxn-1; i+=lowbit(i))s1[i]+=x;
}
void add2(int pos, LL x)
{
for(int i=pos; i<=maxn-1; i+=lowbit(i))s2[i]+=x;
}
LL sum(int pos, LL v[])
{
LL res=0;
for(int i=pos; i>0; i-=lowbit(i))res+=v[i];
return res;
}
void solve()
{
cin>>n>>m;
LL ans=0, sign=1;
// memset(s1, 0, sizeof(s1));
// memset(s2, 0, sizeof(s2));
for(LL i=1; i<=n; i++){
cin>>a[i];
add1(i, sign*a[i]);
add2(i, sign*i*a[i]);
sign*=-1;
}
string in;
// for(int i=1; i<=n; i++)cout<<sum(i, s1)<<endl;
while(m--)
{
cin>>in;
if(in[0]=='Q')
{
LL l, r;
cin>>l>>r;
// cout<<sum(r,s2)-sum(l-1, s2)-(l-1)*(sum(r,s1)-sum(l-1,s1))<<endl;
sign=l%2?1:-1;
// cout<<sum(r,s1)-sum(l-1,s1)<<endl;
ans+=sign*(sum(r,s2)-sum(l-1, s2)-(l-1)*(sum(r,s1)-sum(l-1,s1)));
}
else
{
LL pos, x;
cin>>pos>>x;
sign=pos%2?1:-1;
add1(pos, sign*x-sign*a[pos]);
add2(pos, sign*pos*x-sign*pos*a[pos]);
a[pos]=x;
}
}
// for(int i=1; i<=n; i++)cout<<a[i]<<" ";cout<<endl;
cout<<ans<<"\n";
sign=-1;
for(LL i=1; i<=n; i++)
{
add1(i, sign*a[i]);
add2(i, sign*i*a[i]);
sign*=-1;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
for(int i=1; i<=t; i++){
cout<<"Case #"<<i<<": ";
solve();
}
return 0;
}