牛牛的Link Power II
树状数组做比较简单,只要维护前缀和就行;
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=500100;
const int M=200100;
const ll mod=1e9+7;
int n,m,tr1[N],tr2[N];
vector<int>ve;
int b[N];
ll ans;
int lowbit(int k){
return k & (-k);
}
void add1(int p,int q){//p点加上q,单点修改
while(p<=n){
tr1[p]+=q;
tr1[p]%=mod;
p+=lowbit(p);
}
}
ll sum1(int p){//单点查询,就是求前缀和
ll s=0;
while(p!=0){
s+=(ll)tr1[p];
s%=mod;
p-=lowbit(p);
}
return s;
}
void add2(int p,int q){//p点加上q,单点修改
while(p<=n){
tr2[p]+=q;
tr2[p]%=mod;
p+=lowbit(p);
}
}
ll sum2(int p){//单点查询,就是求前缀和
ll s=0;
while(p!=0){
s+=(ll)tr2[p];
s%=mod;
p-=lowbit(p);
}
return s;
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
string s;
cin>>s;
cin>>m;
for(int i=0;i<n;i++){
if(s[i]=='1') {
add1(i+1,i+1);
add2(i+1,1);
ve.push_back(i+1);
}
}
if(ve.size()==1||ve.size()==0) cout<<0<<endl;
else if(ve.size()==2){
ans=ve[1]-ve[0];
cout<<ve[1]-ve[0]<<endl;
}
else{
ll sum=ve[1]-ve[0];
sum%=mod;
ans=sum;
for(int i=2;i<ve.size();i++){
sum+=(ll)(ve[i]-ve[i-1])*(ll)(i);
sum%=mod;
ans+=sum;
ans%=mod;
}
cout<<ans<<endl;
}
for(int i=1;i<=m;i++){
int q,p;
cin>>q>>p;
if(q==1){
ll t1=(ll)p*(sum2(p-1)-sum2(0))%mod-(sum1(p-1)-sum1(0));
ll t2=(sum1(n)-sum1(p))-(ll)p*(sum2(n)-sum2(p))%mod;
ans=((ans+t1+t2)%mod+mod)%mod;
cout<<ans<<endl;
add1(p,p);
add2(p,1);
}
else{
ll t1=(ll)p*(sum2(p-1)-sum2(0))%mod-(sum1(p-1)-sum1(0));
ll t2=(sum1(n)-sum1(p))-(ll)p*(sum2(n)-sum2(p))%mod;
ans=((ans-t1-t2)%mod+mod)%mod;
cout<<ans<<endl;
add1(p,-p);
add2(p,-1);
}
}
return 0;
}