[luogu6466]分散层叠算法
做法1
对于每一个询问,直接暴力在每一个序列中二分查询
时间复杂度为$o(nk)-o(k\log n)$
做法2
将所有序列合并后排序,并对每一个元素预处理出每个序列中第一个大于等于其的元素(位置),那么只需要在总序列中二分并输出该位置预处理的答案即可
关于这个预处理,显然只需要从后往前扫描一遍总序列即可
时间复杂度为$o(nk^{2})-o(k+\log nk)$
做法3
使用分治归并,并对合并后序列的每一个元素预处理出参与合并的两个序列第一个大于等于其的元素位置
对于查询,只需要在总序列中二分一次,并根据预处理的信息递归下去即可
时间复杂度为$o(nk\log k)-o(k+\log nk)$
做法4
事实上,只需要将下标为偶数的项参与合并,此时即找到第一个大于等于"其"的偶数项,再判断上一项是否大于等于"其"即可,这样查询的复杂度并没有变化
(另外,为了避免特判可以强制将最后一项也加入)
沿用做法3,并做此优化,归纳可得每一个位置上的序列长度都为$n$,复杂度即降为$o(nk)$
当然,直接沿用做法2也是可以的,即令$\{b_{k}\}=\{a_{k}\}$且$\{b_{i}\}$为$\{a_{i}\}$和$\{b_{i+1}\}$合并的结果,同样在合并后预处理相同的信息,通过此优化不难证明$\{b_{i}\}$的长度和为$o(nk)$
时间复杂度为$o(nk)-o(k+\log nk)$

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 10005
4 #define K 105
5 #define D 2
6 int n,k,m,d,x,ans,num[11],a[K][N],Pos[2],b[K][N<<1],pos[K][N<<1][2];
7 int read(){
8 int x=0;
9 char c=getchar();
10 while ((c<'0')||(c>'9'))c=getchar();
11 while ((c>='0')&&(c<='9')){
12 x=x*10+(c-'0');
13 c=getchar();
14 }
15 return x;
16 }
17 void write(int x,char c='\0'){
18 while (x){
19 num[++num[0]]=x%10;
20 x/=10;
21 }
22 if (!num[0])putchar('0');
23 while (num[0])putchar(num[num[0]--]+'0');
24 putchar(c);
25 }
26 int main(){
27 n=read(),k=read(),m=read(),d=read();
28 for(int i=1;i<=k;i++)
29 for(int j=1;j<=n;j++)a[i][j]=read();
30 for(int i=k;i;i--){
31 int x=1,y=D;
32 while ((x<=n)||(y<=b[i+1][0])){
33 if ((x<=n)&&((y>b[i+1][0])||(a[i][x]<b[i+1][y]))){
34 b[i][++b[i][0]]=a[i][x];
35 pos[i][b[i][0]][0]=x++;
36 }
37 else{
38 b[i][++b[i][0]]=b[i+1][y];
39 pos[i][b[i][0]][1]=y;
40 if (y==b[i+1][0])y+=D;
41 else y=min(y+D,b[i+1][0]);
42 }
43 }
44 memset(Pos,0,sizeof(Pos));
45 for(int j=b[i][0];j;j--)
46 for(int p=0;p<2;p++){
47 if (pos[i][j][p])Pos[p]=pos[i][j][p];
48 pos[i][j][p]=Pos[p];
49 }
50 }
51 for(int i=1;i<=m;i++){
52 x=read(),x^=ans;
53 ans=0;
54 int y=lower_bound(b[1]+1,b[1]+b[1][0]+1,x)-b[1];
55 for(int j=1;j<=k;j++){
56 if (pos[j][y][0])ans^=a[j][pos[j][y][0]];
57 if (!pos[j][y][1])break;
58 y=pos[j][y][1];
59 while ((y>1)&&(b[j+1][y-1]>=x))y--;
60 }
61 if (i%d==0)write(ans,'\n');
62 }
63 return 0;
64 }
拓展
给定一张$k$个点的DAG,每个点上有一个长为$n$的单调不下降序列$\{a_{i}\}$
$m$次询问$x$和一条路径,求出每一个路径上的序列中第一个大于等于$z$的元素
保证每一个点的入度和出度均不超过$d$
题解:
类似于做法4,在叶子上令$\{b_{leaf}\}=\{a_{leaft}\}$且$\{b_{i}\}$为$\{a_{i}\}$和$\forall (i,j)\in E,\{b_{j}\}$合并的结果(后者合并时只取下标为$d+1$的倍数的项),并预处理相同的信息
令$L_{i}$为$i$上序列的长度,则有$L_{i}=n+\frac{\sum_{(i,j)\in E}L_{j}}{d+1}$,进而有
$$
\sum_{i\in V}L_{i}=\sum_{i\in V}(n+\frac{\sum_{(i,j)\in E}L_{j}}{d+1})\le \sum_{i\in V}(n+\frac{d}{d+1}L_{i})
$$
将其化简,也即$\sum_{i\in V}L_{i}\le (d+1)nk$
简单分析,可以发现预处理的时空复杂度均为$o(d\sum_{i\in V}L_{i})$,由此也即$o(d^{2}nk)$
另外,由于只取了$d+1$的倍数项,查询时最多要向前找$d$次,即最坏要找$o(dk)$次
(显然$d$要很小此做法才较优,因此二分做到$o(k\log d)$没有意义)
时间复杂度为$o(d^{2}nk)-o(dk+\log nk)$
[luogu6466]分散层叠算法的更多相关文章
- Note/Solution -「洛谷 P6466」分散层叠算法
\(\mathcal{Description}\) Link. 给定 \(m\) 个长度为 \(n\) 的有严格升序且不包含重复元素的序列 \(a_1,a_2,\cdots,a_m\),\(q ...
- [Comet1173]最简单的题
称区间$[l,r]$的"信息"为其的答案和第一个.最后一个大于$x$的位置,显然通过$[l,mid]$和$[mid+1,r]$的信息可以$o(1)$合并得到$[l,r]$的信息 考 ...
- [loj6278]数列分块入门2
做法1 以$K$为块大小分块,并对每一个块再维护一个排序后的结果,预处理复杂度为$o(n\log K )$ 区间修改时将整块打上标记,散块暴力修改并归并排序,单次复杂度为$o(\frac{n}{K}+ ...
- [cf1178G]The Awesomest Vertex
2020年论文题,这里给出了一个$o(n\log^{2}n+m\log^{3}n)$的做法,例题3即为原题 1.例题1 题面 给定$n$个一次函数$f_{i}(x)$,$m$次查询$F(x)=\max ...
- 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率
原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...
- 前端入门4-CSS属性样式表
本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 声明 本系列文章内容全部梳理自以下四个来源: <HTML5权威指南> <JavaScript权威指南> MD ...
- 前端入门3-CSS基础
本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 声明 本系列文章内容全部梳理自以下四个来源: <HTML5权威指南> <JavaScript权威指南> MD ...
- CSS概念【记录】
1.CSS语法 2.@规则 3.注释 4.层叠 5.优先级 6.继承 7.值 8.块格式化上下文 9.盒模型 10.层叠上下文 11.可替换元素 12.外边距合并 13.包含块 14.视觉格式化模型 ...
- CSS学习摘要-语法和选择器
主要摘自网络开发者. 从最基本的层次来看,CSS是由两块内容组合而成的: 属性(Property):一些人类可理解的标识符,这些标识符指出你想修改哪一些样式,例如:字体,宽度,背景颜色等. 属性值(V ...
随机推荐
- UE4技术总结——委托
UE4技术总结--委托 目录 UE4技术总结--委托 一.定义 二.用法 2.1 声明与调用委托 2.1.1 单播委托 2.1.1.a 声明 2.1.1.b 绑定 2.1.1.c 执行委托 2.1.1 ...
- 洛谷 P1862 输油管道问题
题意 题目链接:P1862 输油管道问题 不难看出每个油井的 \(x\) 坐标是没用的,所以问题转化为如下. 代数意义:给出 \(n\) 个数 \(y_1,y_2,\ldots,y_n\),找一个数 ...
- 梦幻西游H5游戏超详细图文架设教程
前言 想体验经典Q版西游霸服快乐吗?想体验满级VIP的尊贵吗?想体验一招秒杀的爽快吗?各种极品装备.翅膀.宠物通通给你,就在梦幻西游! 本文讲解梦幻西游H5游戏的架设教程,想研究H5游戏如何实现,体验 ...
- SignalR 在React/GO技术栈的生产应用
哼哧哼哧半年,优化改进了一个运维开发web平台. 本文记录SignalR在react/golang 技术栈的生产小实践. 1. 背景 有个前后端分离的运维开发web平台, 后端会间隔5分钟同步一次数据 ...
- 从零到熟悉,带你掌握Python len() 函数的使用
摘要:本文为你带来如何找到长度内置数据类型的使用len() 使用len()与第三方数据类型 提供用于支持len()与用户定义的类. 本文分享自华为云社区<在 Python 中使用 len() 函 ...
- Ysoserial Commons Collections7分析
Ysoserial Commons Collections7分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...
- ShardingSphere学习
1 基本概念 1.1 ShardingSphere概述 官网:https://shardingsphere.apache.org/index_zh.html 1.2 分库分表概述 分库分表是为了解决由 ...
- .Net 5下的单文件部署
由于.net程序没有静态链接,一直缺乏单文件部署这种干净的发布方案.对客户端程序发布并不是很友好.在之前的.net framework下,有ILMerge合并程序集,以及LibZ的嵌入资源文件等第三方 ...
- Java:ArrayList类小记
Java:ArrayList类小记 对 Java 中的 ArrayList类,做一个微不足道的小小小小记 概述 java.util.ArrayList 是大小可变的数组的实现,存储在内的数据称为元素. ...
- [对对子队]Beta设计和计划
需求再分析 Alpha阶段用户反馈的问题主要有三个 新手引导部分没有明确指出合成按钮可以使用下拉框切换目标,因此不少玩家卡在第三关 觉得合成动画太长,希望可以快进或者跳过 对游戏目标很迷惑,不知道为什 ...