题目链接
https://acm.hdu.edu.cn/showproblem.php?pid=3074
问题分析
- 从题目中我们可以看出,我们要进行的操作时区间求值和单点修改。并且在每次更新时需要取模。(好水)
代码片段
- 建树
void build(ll s,ll t, ll p)
{
tree[p].l = s,tree[p].r = t;
if (s == t)
{
tree[p].val = a[s];
return;
}
ll mid = (s + t) >> 1;
build(s, mid, p << 1);
build(mid + 1, t, p << 1 | 1);
push_up(p);
return;
}
- 更新上层操作
void push_up(ll p)
{
tree[p].val = tree[p << 1].val * tree[p << 1 | 1].val % mod;
return;
}
- 单点修改
void update(ll k, ll x, ll p)
{
if (tree[p].l == tree[p].r)
tree[p].val = x % mod;
ll mid = (tree[p].l ++ tree[p].r) >> 1;
if (k <= mid) update(k, x, p << 1);
else update(k, x, p << 1 | 1);
push_up(p);
}
- 区间求值
ll query(ll s, ll t, ll p)
{
if (tree[p].l == s && tree[p].r == t) return tree[p].val;
ll mid = (tree[p].l + tree[p].r) >> 1;
if (s <= mid)
return query(s, t, pos << 1);
else if (t > mid)
return query(s, t, pos << 1 | 1);
else
{
ll a = query(s, mid, pos << 1);
ll b = query(mid + 1, t, pos >> 1);
return a * b % mod;
}
}
完整代码
#include <bits/stdc++.h>
/* --------------- fast io begin--------------- */
namespace Fread
{
const int SIZE = 1 << 21;
char buf[SIZE], *S, *T;
inline char getchar()
{
if (S == T)
{
T = (S = buf) + fread(buf, 1, SIZE, stdin);
if (S == T)
return '\n';
}
return *S++;
}
} // namespace Fread
namespace Fwrite
{
const int SIZE = 1 << 21;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush()
{
fwrite(buf, 1, S - buf, stdout);
S = buf;
}
inline void putchar(char c)
{
*S++ = c;
if (S == T)
flush();
}
struct NTR
{
~NTR() { flush(); }
} ztr;
} // namespace Fwrite
#ifdef ONLINE_JUDGE
#define getchar Fread ::getchar
#define putchar Fwrite ::putchar
#endif
namespace Fastio
{
struct Reader
{
template <typename T>
Reader &operator>>(T &x)
{
char c = getchar();
T f = 1;
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
x = 0;
while (c >= '0' && c <= '9')
{
x = x * 10 + (c - '0');
c = getchar();
}
x *= f;
return *this;
}
Reader &operator>>(char &c)
{
c = getchar();
while (c == '\n' || c == ' ')
c = getchar();
return *this;
}
Reader &operator>>(char *str)
{
int len = 0;
char c = getchar();
while (c == '\n' || c == ' ')
c = getchar();
while (c != '\n' && c != ' ')
{
str[len++] = c;
c = getchar();
}
str[len] = '\0';
return *this;
}
Reader() {}
} cin;
const char endl = '\n';
struct Writer
{
template <typename T>
Writer &operator<<(T x)
{
if (x == 0)
{
putchar('0');
return *this;
}
if (x < 0)
{
putchar('-');
x = -x;
}
static int sta[45];
int top = 0;
while (x)
{
sta[++top] = x % 10;
x /= 10;
}
while (top)
{
putchar(sta[top] + '0');
--top;
}
return *this;
}
Writer &operator<<(char c)
{
putchar(c);
return *this;
}
Writer &operator<<(char *str)
{
int cur = 0;
while (str[cur])
putchar(str[cur++]);
return *this;
}
Writer &operator<<(const char *str)
{
int cur = 0;
while (str[cur])
putchar(str[cur++]);
return *this;
}
Writer() {}
} cout;
} // namespace Fastio
#define cin Fastio ::cin
#define cout Fastio ::cout
#define endl Fastio ::endl
/* --------------- fast io end--------------- */
//程序从此开始
#define ll long long
using namespace std;
const ll maxn = 1e5 + 10;
const ll mod = 1000000007;
ll A[maxn];
struct node
{
ll L, R, val;
} tree[maxn << 2];
void push_up(int pos)
{
tree[pos].val = tree[pos << 1].val * tree[pos << 1 | 1].val % mod;
return;
}
void build(ll s, ll t, ll pos)
{
tree[pos].L = s;
tree[pos].R = t;
if (s == t)
{
tree[pos].val = A[s] % mod;
return;
}
ll mid = (s + t) >> 1;
build(s, mid, pos << 1);
build(mid + 1, t, pos << 1 | 1);
push_up(pos);
return;
}
ll query(int l, int r, int pos)
{
if (tree[pos].L == l && tree[pos].R == r)
{
return tree[pos].val;
}
int mid = (tree[pos].L + tree[pos].R) >> 1;
if (r <= mid)
return query(l, r, pos << 1);
else if (l > mid)
return query(l, r, pos << 1 | 1);
else
{
ll a = query(l, mid, pos << 1);
ll b = query(mid + 1, r, pos >> 1);
return a * b % mod;
}
}
void update(ll k, ll x, ll pos) // a[k] = x
{
if (tree[pos].L == k && k == tree[pos].R)
{
tree[pos].val = x % mod;
return;
}
ll mid = (tree[pos].L + tree[pos].R) >> 1;
if (k <= mid)
update(k, x, pos << 1);
else
update(k, x, pos << 1 | 1);
push_up(pos);
}
int main()
{
ll t, n, m;
cin >> t;
while (t--)
{
cin >> n;
memset(A, 0, sizeof(A));
memset(tree, 0, sizeof(tree));
for (ll i = 1; i <= n; i++)
cin >> A[i];
build(1, n, 1);
ll cnt;
cin >> cnt;
while (cnt--)
{
ll type;
cin >> type;
if (type == 0)
{
ll s, t;
cin >> s >> t;
cout << query(s, t, 1) << endl;
}
else
{
ll k, x;
cin >> k >> x;
update(k, x, 1);
}
}
}
return 0;
}