从CF1660F2看同余分组

https://codeforces.com/contest/1660/problem/F2

同余分组,树状数组维护逆序对

先承继F1的做法,维护一个前缀和数组,让 s[i] == '+'1s[i] == '-'1

那么要满足两个条件:

  • prerprel0
    • 要么加减号相同,要么减号更多(只有减号能减少)
  • prerprel0(mod3)
    • 两个减号变成一个加号,相差为三的倍数。

其中第二个条件可以同余转化为

prerprel(mod3)

而第一个条件显然 l<r​,那么第一个条件等效于求逆序对。

而要求的逆序对还要满足 prerprel(mod3),可以发现三的余数极少,所以对于三的每个余数分别开树状数组来维护逆序对就能满足两个条件。

void solve() { int n; std::cin >> n; std::string s; std::cin >> s; std::vector<int> pre(n + 1); for (int i = 0; i < n; i++) {pre[i + 1] = pre[i] + (s[i] == '+' ? 1 : -1);} //对%3的余数分组开Fenwick //0, 1, 2 std::vector fenwicks(3, Fenwick<int>(n * 2 + 1)); auto get = [&](int x) {return (x % 3 + 3) % 3;}; i64 ans = 0; for (int i = n; i >= 0; i--) { ans += fenwicks[get(pre[i])].sum(pre[i] + n + 1);//用pre[i] % 3 的余数来分组,在组内求逆序对。 fenwicks[get(pre[i])].add(pre[i] + n, 1); } std::cout << ans << '\n'; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/18218804.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示