2022.1.22 总结

2022.1.22 总结

哎呀,今天又爆炸了。

赛时:

这个 T1 怎么 n 这么大,吓唬人的吧。但是咋做呢,可能有循环节吧,那不是乱做。哎呀一会再回来写,似乎挺麻烦的。

这个 T2 怎么又一股搜索味,有点恶心,决定先看后面的。

这个 T3 不是二元关系网络流版题?先秒了。

这个 T4 有点意思。貌似类似一类三维偏序问题呀,但是又有一些奇怪的地方不好做,也许只能树套树了。

经过严峻的思考我想出了一个成功的线段树套 set 做法!考虑在线地处理每一个问题,线段树的区间维护的是纵坐标,每个区间维护两个 set,一个表示的是覆盖当前区间的矩形,一个表示子树内的所有矩形的总和。在查询的时候只需查区间里面的 小于等于当前查询矩形左边界的 矩形右边界最大值就好了。

核心代码如下:

inline void insert(int t, int l, int r, int fl, int fr, int v) {
    sum[t].insert(v);
    if(fl <= l && r <= fr)  return (void)(val[t].insert(v));
    fl <= mid && (insert(ls, l, mid, fl, fr, v), 1);
    fr > mid && (insert(rs, mid + 1, r, fl, fr, v), 1);
}
inline void change(int t, int l, int r, int fl, int fr, int v1, int v2) { // v1 != v2
    sum[t].erase(sum[t].find(v1));
    sum[t].insert(v2);
    if(fl <= l && r <= fr)  return (void)(val[t].erase(val[t].find(v1)), val[t].insert(v2));
    fl <= mid && (change(ls, l, mid, fl, fr, v1, v2), 1);
    fr > mid && (change(rs, mid + 1, r, fl, fr, v1, v2), 1);
}
inline int query(int t, int l, int r, int fl, int fr, int lim) {
    if(fl <= l && r <= fr) {
        auto it = sum[t].upper_bound(lim);
        return it == sum[t].begin() ? 0 : *(--it);
    }
    auto it = val[t].upper_bound(lim);
    int ret = it == val[t].begin() ? 0 : *(--it);
    fl <= mid && (ret = max(ret, query(ls, l, mid, fl, fr, lim)));
    fr > mid && (ret = max(ret, query(rs, mid + 1, r, fl, fr, lim)));
    return ret;
}

这个东西耗费了我极长的时间,在后面调试、对拍、卡常更是耗费了我很大的精力。

于是第一题就忘了去打。然后就炸了。

赛后:

啊 T1 果然是一个水题。 T2 果然是双向搜索。 T4 可以有更美好的做法,但是时间复杂度不能保证,现在我仍不知道正解的做法。

总结就是,不要死磕一道题。在做难题之前一定把能保的题先保住。

posted @   Martin_MHT  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示