社区讨论

感觉思路正确但WA,求大佬帮忙看一眼

P9871[NOIP2023] 天天爱打卡参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@m3zqczpn
此快照首次捕获于
2024/11/27 18:15
去年
此快照最后确认于
2025/11/04 13:48
4 个月前
查看原帖
rt,感觉dp的思路没什么问题,不知道是线段树写挂了还是思路假了,求大佬帮忙看一下
不用管为什么是动态开点而不是离散化,太懒了只想看看大概思路对不对,就没有写离散化
CPP
#include <bits/stdc++.h>
#define ll long long
#define maxn 100010
#define mid ((l + r) >> 1)
using namespace std;
#define writeln(X) write(X), putchar('\n')
template < typename T >
inline void read(T &X)
{
    X = 0; bool f = false; char ch = getchar();
    while (!isdigit(ch)) {f |= ch == '-'; ch = getchar();}
    while (isdigit(ch)) {X = (X * 10) + (ch ^ 48); ch = getchar();}
    X = f ? -X : X;
}
template < typename T >
inline void write(T X)
{
    if (X == 0) {putchar('0'); return;}
    if (X < 0) {putchar('-'); X = -X;}
    static char cnt = 0, num[20];
    while (X) *(num + cnt++) = X % 10, X /= 10;
    while (cnt) putchar(*(num + --cnt) ^ 48);
    return;
}
int c, t;
int n, m, k, d;
ll ans;
int rt = 1;
ll val[maxn << 6], lazy[maxn << 6];
int lson[maxn << 6], rson[maxn << 6];
int cnt;
inline void merge(const int &x) 
{
    if (lson[x]) val[x] = max(val[x], val[lson[x]]);
    if (rson[x]) val[x] = max(val[x], val[rson[x]]);
    return;
}
inline void push(const int &x, const int &r)
{
    if (val[x] == 0) val[x] = lazy[x] + 1ll * d * r;
    else val[x] += lazy[x];
    lazy[lson[x]] += lazy[x], lazy[rson[x]] += lazy[x];
    lazy[x] = 0;
    return;
}
void add(int &x, const int &l, const int &r, const int &lx, const int &rx, const int &v)
{
    if (x == 0) x = ++cnt;
    if (lazy[x]) push(x, r);
    if (l >= lx && r <= rx) {lazy[x] += v; push(x, r); return;}
    if (mid >= lx) add(lson[x], l, mid, lx, rx, v);
    if (mid + 1 <= rx) add(rson[x], mid + 1, r, lx, rx, v);
    merge(x);
}
ll query(int &x, const int &l, const int &r, const int &lx, const int &rx)
{
    if (x == 0) return 0;
    if (lazy[x]) push(x, r);
    if (l >= lx && r <= rx) return val[x];
    ll res = 0;
    if (mid >= lx) res = max(res, query(lson[x], l, mid, lx, rx));
    if (mid + 1 <= rx) res = max(res, query(rson[x], mid + 1, r, lx, rx));
    return res;
}
struct line
{
    int l, r; ll v;
    line(const int &_l, const int &_r, const ll &_v) : l(_l), r(_r), v(_v) {}
    bool operator < (const line &b) const {return this->r == b.r ? this->l < b.l : this->r < b.r;}
};
vector < line > linelist;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("P9871.in", "r", stdin);
    freopen("P9871.out", "w", stdout);
#endif
    read(c); read(t);
    while (t--)
    {
        read(n); read(m); read(k); read(d);
        memset(val, 0, sizeof(val)); memset(lazy, 0, sizeof(lazy));
        memset(lson, 0, sizeof(lson)); memset(rson, 0, sizeof(rson));
        cnt = 1; ans = 0;
        linelist.clear();
        for (int i = 1; i <= m; ++i)
        {
            int x, y, v;
            read(x); read(y); read(v);
            if (y > k) continue;
            linelist.emplace_back(x - y + 1, x, v);
        }
        sort(linelist.begin(), linelist.end());
        int lr = 0; ll lres = 0;
        for (line x : linelist)
        {
            if (lr != x.r && lres) {add(rt, 0, n, lr + 1, n, lres); lres = 0;}
            //处理完一个坐标后加入线段树
            //运动到r,说明下次休息在r + 1及以后
            add(rt, 0, n, 0, x.l - 1, x.v);
            //加入当前线段
            //l时开始打卡,说明上次休息在l - 1及之前
            ll res = max(0ll, query(rt, 0, n, x.r - k, x.r) - 1ll * d * x.r); ans = max(ans, res);
            //寻找上次休息在r - k~r中的最大值
            lr = x.r, lres = max(lres, res);
        }
        writeln(ans);
    }
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...