链接: link.
题解思路:
分块的思想,加法的一块,乘法的放在一块,然后对于该块进行更新的时候,使用逆元的方式进行更新(加法的块和乘法的块,都可以用逆元去进行处理)
#include <bits/stdc++.h>
#define int long long
#define go continue
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define forl(i,a,b) for(int i = a; i < b; ++i)
using namespace std;
const int N = 1e6 + 7;
const int mod = 1e9 + 7;
int ffp(int a, int b) {
int ok = 1;
while(b) {
if(b & 1) ok = ok * a % mod;
a = a * a % mod;
b >>= 1;
}
return ok % mod;
}
int a[N], vis[N], cnt[N];
int n, m, len;
string s;
int sum, tmp, idx;
int x, y;
signed main() {
IOS;
cin >> n >> m >> s;
s.push_back('+');
len = s.size();
forl(i, 0, n) cin >> a[i];
sum = idx = 0;
tmp = a[0];
//处理值
forl(i, 0, len) {
if(s[i] == '+') {
sum = (sum + tmp) % mod;
cnt[idx++] = tmp;
vis[i + 1] = idx;
tmp = a[i + 1];
} else {
tmp = (tmp * a[i + 1]) % mod;
vis[i + 1] = idx;
}
}
forl(i, 0, m) {
cin >> x >> y;
x--;
//减去当前块
sum = (sum - cnt[vis[x]] + mod) % mod;
//更新当前块
cnt[vis[x]] = ((cnt[vis[x]] * ffp(a[x], mod - 2) % mod)) * y % mod;
//加上更新后的块
sum = (sum + cnt[vis[x]]) % mod;
a[x] = y;
cout << sum << endl;
}
return 0;
}
/*
5 3
++*+
1 1 3 1 1
4 2
1 7
5 6
*/