【luogu P6466】分散层叠算法(Fractional Cascading)(二分)(模板)

分散层叠算法(Fractional Cascading)

题目链接:luogu P6466

题目大意

给你 k 个长度为 n 的有序数组,然后要你在线查询:
给你一个数 x,求每个数组 x 的非严格后继的异或和。

思路

首先考虑一些暴力之类的?
不难想到 O(nklogn) 的二分暴力。

然后你考虑一个神奇的方法:
弄一个二维数组 B,然后第 i 维除了放第 i 个有序数组,你还可以放第 i+1 维的数组中偶数位的部分。(这个可以归并排序实现)
这样有什么用呢?你会发现你如果求这个数组二分的答案,它原来的有序数组的答案其实可以用这个的答案在二分得到(而且其实就没有必要二分了,直接找后面第一个是原来有序数组的数,可以在归并排序的时候得到)。
然后你要求 i+1 的数组的答案的时候,你会发现你又像上面一样搞,位置的相差竟然至多是 1

然后你考虑你 B 数组每一维的数量,考虑每个的贡献,当前的是 1,隔一个是 12,然后 14,所以总的来讲不到 2

然后你就可以 O(nk+qlogn+qk) 做了。


然后可以小小扩展一下,如果给定是一个图然后每个点有一个数列,度数不超过一个值 d,每次询问是求图上一条链的每个点的答案。
那我们这里就是隔 d 个选一个,然后预处理的部分就是乘上一个 logd

它其实有一个类似均摊的感觉,所以你可以和分块之类的结合起来,但是我就不会啦awa。
(不过你可以参考 IOI 2020 中国国家候选队论文《浅谈利用分散层叠算法对经典分块问题的优化》)

代码

#include<cstdio> #include<algorithm> using namespace std; const int N = 10000 + 10; const int K = 100 + 10; const int Q = 500000 + 10; struct node { int x, nxt1, nxt2; }b[K][N << 1]; int n, k, q, d, lstans, sz[K], a[K][N], fir[N << 1], x; int main() { scanf("%d %d %d %d", &n, &k, &q, &d); for (int i = 1; i <= k; i++) for (int j = 1; j <= n; j++) scanf("%d", &a[i][j]); sz[k] = n; for (int i = 1; i <= n; i++) b[k][i] = (node){a[k][i], i, 0}; for (int i = k - 1; i >= 1; i--) { int x = 1, y = 2, nxt1 = 0, nxt2 = 0; while (x <= n && y <= sz[i + 1]) { if (a[i][x] < b[i + 1][y].x) nxt1 = x, b[i][++sz[i]] = (node){a[i][x], nxt1, nxt2 + 1}, x++; else nxt2 = y, b[i][++sz[i]] = (node){b[i + 1][y].x, nxt1 + 1, nxt2}, y = y + 2; } while (x <= n) nxt1 = x, b[i][++sz[i]] = (node){a[i][x], nxt1, nxt2 + 1}, x++; while (y <= sz[i + 1]) nxt2 = y, b[i][++sz[i]] = (node){b[i + 1][y].x, nxt1 + 1, nxt2}, y = y + 2; } for (int i = 1; i <= sz[1]; i++) fir[i] = b[1][i].x; for (int t = 1; t <= q; t++) { scanf("%d", &x); x ^= lstans; int p = lower_bound(fir + 1, fir + sz[1] + 1, x) - fir; lstans = 0; for (int i = 1; i <= k; i++) { while (p <= sz[i] && b[i][p].x < x) p++; while (p >= 2 && b[i][p - 1].x >= x) p--; if (p <= sz[i]) { lstans ^= a[i][b[i][p].nxt1]; p = b[i][p].nxt2; } else p = sz[i + 1] + 1; } if (t % d == 0) { printf("%d\n", lstans); } } return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/luogu_P6466.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示