题解:AT_abc255_h [ABC255Ex] Range Harvest Query

· · 题解

\Large{\text{Solution}}

调了若干时间,大脑不够清晰吧,最开始逻辑都有问题,吃了 11 发罚时(本题请勿 #define int long long)。

线段树维护一下内容: ::::info[node of segment_tree]{open}

可以放到线段树上做。每次询问前,给根节点打上懒标记,加上从上次询问到现在,树又长了多少天。然后开始查询。

查询正常查,到返回的区间时打上标记,把这个区间清空,回去的时候也要 pushup

\Large{\text{Code}}
#include <bits/stdc++.h>
// #define int long long
#define x first
#define y second
#define ls(u) tr[u].ls 
#define rs(u) tr[u].rs 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <int, pii> piii;
const double PI = acos (-1);
const double eps = 1e-10;
const int N = 2e5 + 10, M = 2e5 + 10;
//const int mod = 1e9 + 7;
const int mod = 998244353, v2 = 499122177;//逆元
struct node
{
    int ls, rs;
    int val, tag;
    bool tag0;
} tr[N * 200];//没具体算,但是得开大点
int idx = 1, root = 1;
ll sum(ll l, ll r, ll k)
{return ((l + r) % mod) * ((r - l + 1) % mod) % mod * v2 % mod * (k % mod) % mod;}//等差数列求和公式

void pushdown(int u, ll l, ll r)
{
    int& tag = tr[u].tag;
    bool& tag0 = tr[u].tag0;
    if (!ls (u)) ls (u) = ++idx;
    if (!rs (u)) rs (u) = ++idx;
    if (tag0)
    {
        tr[ls (u)].tag0 = tr[rs (u)].tag0 = true;
        tr[ls (u)].val = tr[rs (u)].val = 0;
        tr[ls (u)].tag = tr[rs (u)].tag = 0;
        tag0 = false;
    }
    if (!tag) return;
    ll mid = l + r >> 1;
    tr[ls (u)].val += sum (l, mid, tag); tr[ls (u)].val %= mod;
    tr[rs (u)].val += sum (mid + 1, r, tag); tr[rs (u)].val %= mod;
    tr[ls (u)].tag += tag; tr[ls (u)].tag %= mod;
    tr[rs (u)].tag += tag; tr[rs (u)].tag %= mod;
    tag = 0;
}
int query(int u, ll L, ll R, ll l, ll r)
{
    // if (R - L + 1 <= 8)
    //     cout << " " << L << " " << R << " " << tr[u].val << "\n";
    if (l <= L && R <= r)
    {
        int val = tr[u].val;
        tr[u].val = tr[u].tag = 0;
        tr[u].tag0 = true;
        return val % mod;
    }
    pushdown (u, L, R);
    ll mid = L + R >> 1, ans = 0;
    if (l <= mid) ans += query (ls (u), L, mid, l, r);
    if (r > mid) ans += query (rs (u), mid + 1, R, l, r);
    tr[u].val = (tr[ls (u)].val + tr[rs (u)].val) % mod;
    return ans % mod;
}
signed main()
{
    cin.tie (0);
    ios::sync_with_stdio (false);
    ll n, q;
    cin >> n >> q;
    ll last = 0;
    while (q--)
    {
        ll l, r, k;
        cin >> k >> l >> r;
        tr[root].val += sum (1, n, (k - last) % mod);
        tr[root].val %= mod;
        tr[root].tag += (k - last) % mod;
        tr[root].tag %= mod;
        cout << (query (root, 1, n, l, r) + mod) % mod << "\n";
        last = k;
    }
    return 0;
}
// void change(int& u, int L, int R, int l, int r, int k)
// {
//     // if (R - L + 1 <= 8)
//     //     cout << "-" << L << " " << R << " " << tr[u].val << "\n";
//     if (!u) u = ++idx;
//     if (l <= L && R <= r)
//     {
//         tr[u].val += sum (L, R, k);
//         tr[u].tag += k;
//         return;
//     }
//     pushdown (u, L, R);
//     int mid = L + R >> 1;
//     if (l <= mid) change (ls (u), L, mid, l, r, k);
//     if (r > mid) change (rs (u), mid + 1, R, l, r, k);
//     tr[u].val = (tr[ls (u)].val + tr[rs (u)].val) % mod;
// }