传送门
思路:
首先对题意要有深刻理解,由于运算是有优先级的,且我们发现每一个+
会区分开一段区间,每个区间的值互不干扰,所以我们可以提前将每一个区间的信息整合到一个值里面,然后进行计算,也就是分块的思想(块内乘积,块间加减),首先预处理第一块:第1个数字在第1块里,第一块的值是a[1]
,最后修改的过程中,定位到所要修改块的位置pos,之后改变块内的值,然后重新计算新值即可
代码:
#include<iostream>
#define int long long
using namespace std;
const int N=1000010,mod=1e9+7;
int a[N],b[N];
int n,q;
int ans[N];
char c[N];
int qmi(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int inv(int a){
return qmi(a,mod-2);
}
signed main(){
cin>>n>>q;
cin>>(c+1);
for(int i=1;i<=n;i++)
cin>>a[i],ans[i]=1;
//预处理第一块:第1个数字在第1块里,第一块的值是a[1]
b[1]=1;
ans[1]=a[1];
int now=1;
for(int i=1;i<=n-1;i++){
//遇到'+',进入下一块
if(c[i]=='+')now++;
//第now块的值是ans[now]
ans[now]=ans[now]*a[i+1]%mod;
//第(i+1)个数字在第now块里
b[i+1]=now;
}
int res=0;
for(int i=1;i<=now;i++)
res=(res+ans[i])%mod;
while(q--){
int x,y;
cin>>x>>y;
//修改的是第pos块的数据,要把old修改为y
int pos=b[x],old=a[x];
int en=ans[pos];
ans[pos]=ans[pos]*inv(old)%mod*y%mod;
int change=((ans[pos]-en)%mod+mod)%mod;
res=(res+change)%mod;
//别忘记
a[x]=y;
cout<<res<<endl;
}
}