HDU - 3074

题目链接

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值