关于线段树
  • 板块灌水区
  • 楼主knya
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/9/10 16:00
  • 上次更新2023/11/2 21:37:30
查看原帖
关于线段树
993783
knya楼主2023/9/10 16:00

题目

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

typedef long long LL;

namespace IO
{
    LL read()
    {
        LL s = 0; bool fu = false;
        char ch = getchar();
        while (ch < '0' || ch > '9')
        {
            if (ch == '-') fu = true;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9')
        {
            s = (s << 1) + (s << 3) + (ch ^ 48);
            ch = getchar();
        }
        return fu ? -s : s;
    }
    void write(LL x)
    {
        static int sta[20];
        if (x < 0) putchar('-'), x = -x;
        int tt = 0;
        do
            sta[tt ++ ] = x % 10,
            x /= 10;
        while (x);
        
        while (tt) putchar(sta[ -- tt]^ 48);
    }
}

using namespace std;
using namespace IO;

const int N = 500010;

struct Node
{
    int l, r;
    LL sum, d;
} tr[N << 2];

LL w[N];

LL gcd(LL x, LL y)
{
    return y ? gcd(y, x % y) : x;
}

void pushup(Node &u, Node &l, Node &r)
{
    u.sum = l.sum + r.sum;
    u.d = gcd(l.d, r.d);
}

void pushup(int u)
{
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r)
{
    if (l == r)
    {
        LL b = w[r] - w[l - 1];
        tr[u] = {l, r, b, b};
    }
    else
    {
        tr[u].l = l, tr[u].r = r;
        int mid = l + r >> 1;
        build(u << 1, l, mid),
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

void modify(int u, int x, LL val)
{
    if (tr[u].l == x && tr[u].r == x)
    {
        LL b = tr[u].sum + val;
        tr[u] = {x, x, b, b};
    }
    else
    {
        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid) modify(u << 1, x, val);
        else modify(u << 1 | 1, x, val);
        pushup(u);
    }
}

Node query(int u, int l, int r)
{
    if (l <= tr[u].l && tr[u].r <= r) return tr[u];
    int mid = tr[u].l + tr[u].r >> 1;
    if (mid >= r) return query(u << 1, l, r);
    else if (mid < l) return query(u << 1 | 1, l, r);
    else
    {
        auto left = query(u << 1, l, r);
        auto right = query(u << 1 | 1, l, r);
        Node res;
        pushup(res, left, right);
        return res;
    }
}

int main()
{
    int n = read(), m = read();
    for (int i = 1; i <= n; ++ i)
        w[i] = read();
    build(1, 1, n);
    char op[2]; LL x, y, d;
    while (m -- )
    {
        scanf("%s", op);
        x = read(), y = read();
        if (op[0] == 'C')
        {
            d = read();
            modify(1, x, d);
            if (y + 1 <= n) modify(1, y + 1, -d);
        }
        else
        {
            auto left = query(1, 1, x);
            Node right = {0, 0, 0, 0};
            if (x + 1 <= y) right = query(1, x + 1, y);
            write(abs(gcd(left.sum, right.d)));
            putchar('\n');
        }
    }
    return 0;
}

问题:

int main()
{
    int n = read(), m = read();
    for (int i = 1; i <= n; ++ i)
        w[i] = read();
    build(1, 1, n);
    char op[2]; LL x, y, d;
    while (m -- )
    {
        scanf("%s", op);
        x = read(), y = read();
        if (op[0] == 'C')
        {
            d = read();
            modify(1, x, d);
            if (y + 1 <= n) modify(1, y + 1, -d);
        }
        else
        {
            auto left = query(1, 1, x);
            Node right = {0, 0, 0, 0};
            if (x + 1 <= y) right = query(1, x + 1, y);
            // 这里为什么不能写成 write(abs(gcd(left.sum, right.sum)));
            // 或 write(abs(gcd(left.d, right.sum)));
            // 或 write(abs(gcd(left.d, right.d)));
            write(abs(gcd(left.sum, right.d)));
            putchar('\n');
        }
    }
    return 0;
}
2023/9/10 16:00
加载中...