P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III

cxqghzj·2023-12-07 10:00·18 次阅读

P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III

题意#

给定序列 s,每次询问 l,r 的区间众数的出现次数。

强制在线。空间:62.5MB

Sol#

蒲公英卡常卡空间版。

考虑优化那个 n×m 的数组。

我们要求 l,r 之中某个数的个数。

乍一看不好弄,仔细想想就会发现,如果我们知道当前的最优答案。在长常数时间内就能知道当前散块是否比最优答案更优。

考虑将每个数按照下标扔进 nvector

直接暴力查询 px+ans 即可。

不难发现,该算法的时间复杂度是正确的。

Code#

Copy
#include <iostream> #include <algorithm> #include <cstdio> #include <array> #include <queue> #include <vector> #include <cassert> #define pii pair <int, int> using namespace std; #ifdef ONLINE_JUDGE #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; #endif int read() { int p = 0, flg = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') flg = -1; c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } return p * flg; } void write(int x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } #define rg register #define il inline #define fi first #define se second const int N = 5e5 + 10, M = 1505; array <int, N> s, h; namespace Blk { int bsi = 433; il int calc(rg int x) { return (x - 1) / bsi + 1; } array <int, N> cur; queue <int> q; int tot; il void add(rg int x, rg int y) { if (!x) return; cur[x] += y; q.push(x); if (cur[x] > cur[tot]) tot = x; else if (cur[x] == cur[tot]) tot = min(tot, x); } il void clear() { while (!q.empty()) cur[q.front()] = 0, q.pop(); tot = 0; } array <array <pii, M>, M> isl; array <vector <int>, N> suf, pre; array <int, N> idx, dfn; il void init(rg int n) { for (rg int i = 1; i <= calc(n); i++) { for (rg int j = i; j <= calc(n); j++) { for (rg int k = (j - 1) * bsi + 1; k <= min(j * bsi, n); k++) add(s[k], 1); isl[i][j] = make_pair(tot, cur[tot]); } clear(); } for (rg int i = 1; i <= n; i++) suf[s[i]].push_back(i), dfn[i] = suf[s[i]].size() - 1; for (rg int i = n; i >= 1; i--) pre[s[i]].push_back(i), idx[i] = pre[s[i]].size() - 1; } il int query(rg int x, rg int y) { if (abs(calc(x) - calc(y)) <= 1) { for (rg int i = x; i <= y; i++) add(s[i], 1); rg int ans = cur[tot]; clear(); return ans; } rg int ans, tot; tie(tot, ans) = isl[calc(x) + 1][calc(y) - 1]; for (rg int i = x; i <= calc(x) * bsi; i++) { while ((int)suf[s[i]].size() > ans + dfn[i] && suf[s[i]][ans + dfn[i]] <= y) ans++, tot = s[i]; /* assert(ans + dfn[i] - 1 >= 0); */ /* if ((int)suf[s[i]].size() > ans + dfn[i] - 1 && suf[s[i]][ans + dfn[i] - 1] <= y) */ /* tot = min(tot, s[i]); */ } for (rg int i = (calc(y) - 1) * bsi + 1; i <= y; i++) { while ((int)pre[s[i]].size() > ans + idx[i] && pre[s[i]][ans + idx[i]] >= x) ans++, tot = s[i]; /* assert(ans + idx[i] - 1 >= 0); */ /* if ((int)pre[s[i]].size() > ans + idx[i] - 1 && pre[s[i]][ans + idx[i] - 1] >= x) */ /* tot = min(tot, s[i]); */ } /* write(ans), puts("@"); */ return ans; } } signed main() { /* freopen("P4168_2.in", "r", stdin); */ rg int n = read(), m = read(); for (rg int i = 1; i <= n; i++) s[i] = h[i] = read(); /* sort(h.begin() + 1, h.begin() + 1 + n); */ /* rg int k = unique(h.begin() + 1, h.begin() + 1 + n) - h.begin() - 1; */ /* for (rg int i = 1; i <= n; i++) */ /* s[i] = lower_bound(h.begin() + 1, h.begin() + 1 + k, s[i]) - h.begin(); */ rg int lst = 0; Blk::init(n); while (m--) { rg int l = read(), r = read(); l = (l ^ lst), r = (r ^ lst); /* l = (l + lst - 1) % n + 1, r = (r + lst - 1) % n + 1; */ if (l > r) swap(l, r); write(lst = Blk::query(l, r)), puts(""); } return 0; }
posted @   cxqghzj  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
目录