题目传送:Multiply game
思路:简单线段树,单点更新,区间求积,这是上次选拔赛选的题,一看题就是线段树,不过当时线段树不太熟,没敢敲,现在看来居然如此轻松,不过注意这里有大量输出,用printf,居然在这里TLE了一次。。。
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cctype>
#define LL long long
#define INF 0x7fffffff
#define MOD 1000000007
using namespace std;
const int maxn = 50005;
int T;
int n;
LL mu[maxn << 2];
void build(int l, int r, int rt) {
if(l == r) {
scanf("%I64d", &mu[rt]);
return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
mu[rt] = (mu[rt << 1] * mu[rt << 1 | 1]) % MOD;
}
LL query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return mu[rt];
}
LL ret = 1;
int mid = (l + r) >> 1;
if(mid >= L) ret = (ret * query(L, R, l, mid, rt << 1)) % MOD;
if(mid + 1 <= R) ret = (ret * query(L, R, mid + 1, r, rt << 1 | 1)) % MOD;
return ret;
}
void update(int p, int v, int l, int r, int rt) {
if(l == r) {
mu[rt] = v;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) update(p, v, l, mid, rt << 1);
else update(p, v, mid + 1, r, rt << 1 | 1);
mu[rt] = (mu[rt << 1] * mu[rt << 1 | 1]) % MOD;
}
int main() {
scanf("%d", &T);
while(T --) {
scanf("%d", &n);
build(1, n, 1);
int q;
scanf("%d", &q);
while(q --) {
int op, a, b;
scanf("%d %d %d", &op, &a, &b);
if(op == 0) {
LL ans = query(a, b, 1, n, 1);
printf("%I64d\n", ans);
}
else if(op == 1) {
update(a, b, 1, n, 1);
}
}
}
return 0;
}