bzoj 4358 Permu - 莫队算法 - 链表
考虑使用莫队算法。
每次插入一个数$x$,对值域的影响可以分成4种情况:
- $x - 1$, $x + 1$都不存在。
 - 只有$x - 1$存在,等价于在一段后面添加一个数
 - 只有$x + 1$存在,等价于在一段前面添加一个数
 - $x - 1$和$x + 1$都存在,等价于把两段拼起来
 
所以只有端点处的信息有用。我们考虑维护端点处的信息。
为了方便区分存在和不存在,我们维护开区间。
每个端点的$pre$指向这一段开头的前一个位置,每个端点的$suf$指向这一段结尾的后一个位置。
然后讨论一下就能更新了。
同时发现在保证顺序的情况下资瓷删除。(不能也没有关系)
然后让莫队回滚一下就做完了。时间复杂度$O(m\sqrt{n})$。
Code
/**
* bzoj
* Problem#4358
* Accepted
* Time: 3600ms
* Memory: 2664k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; const int cs = ; typedef class Query {
public:
int l, r, id, res; boolean operator < (Query b) const {
if ((l >> ) != (b.l >> ))
return (l >> ) < (b.l >> );
return r < b.r;
}
}Query; int n, m;
int *ar;
int *suf, *pre;
Query* qs; inline void init() {
scanf("%d%d", &n, &m);
ar = new int[(n + )];
suf = new int[(n + )];
pre = new int[(n + )];
qs = new Query[(m + )];
for (int i = ; i < n; i++)
scanf("%d", ar + i);
for (int i = ; i < m; i++) {
scanf("%d%d", &qs[i].l, &qs[i].r);
qs[i].l--, qs[i].r--, qs[i].id = i;
}
} boolean exist(int x) {
return pre[x] != suf[x];
} void insert(int x, int& res) {
boolean sgnpre = exist(x - ), sgnsuf = exist(x + );
if (!sgnpre && !sgnsuf) {
pre[x] = x - ;
suf[x] = x + ;
res = max(res, );
} else if (sgnpre && !sgnsuf) {
int front = pre[x - ];
pre[x] = front, suf[x] = x + ;
suf[front + ] = x + ;
res = max(res, x - front);
} else if (sgnsuf && !sgnpre) {
int rear = suf[x + ];
pre[x] = x - , suf[x] = rear;
pre[rear - ] = x - ;
res = max(res, rear - x);
} else {
int front = pre[x - ], rear = suf[x + ];
pre[x] = front, suf[x] = rear;
suf[front + ] = rear, pre[rear - ] = front;
res = max(res, rear - front - );
}
} void remove(int x) {
boolean sgnpre = exist(x - ), sgnsuf = exist(x + );
if (!sgnpre && !sgnsuf)
pre[x] = suf[x] = x;
else if (sgnpre && !sgnsuf) {
int front = pre[x];
pre[x] = suf[x] = suf[front + ] = x;
} else if (sgnsuf && !sgnpre) {
int rear = suf[x];
pre[x] = suf[x] = pre[rear - ] = x;
} else {
int front = pre[x], rear = suf[x];
pre[x] = suf[x] = x;
suf[front + ] = pre[rear - ] = x;
}
} inline void solve() {
sort(qs, qs + m);
Query* q = qs, *ped = qs + m;
for (int sid = ; q != ped; sid++) {
int ed = cs * (sid + ), mdzzr = ed - ;
for (int i = ; i <= n + ; i++)
pre[i] = suf[i] = i;
int cures = ;
for ( ; q != ped && (q->l >> ) == sid; q++) {
if ((q->r >> ) == sid) {
q->res = ;
for (int i = q->l; i <= q->r; i++)
insert(ar[i], q->res);
for (int i = q->r; i >= q->l; i--)
remove(ar[i]);
} else {
while (mdzzr < q->r)
insert(ar[++mdzzr], cures);
int nres = cures;
for (int i = ed - ; i >= q->l; i--)
insert(ar[i], nres);
q->res = nres;
for (int i = q->l; i < ed; i++)
remove(ar[i]);
}
}
}
for (int i = ; i < m; i++)
while (qs[i].id != i)
swap(qs[i], qs[qs[i].id]);
for (int i = ; i < m; i++)
printf("%d\n", qs[i].res);
} int main() {
init();
solve();
return ;
}
bzoj 4358 Permu - 莫队算法 - 链表的更多相关文章
- 【BZOJ】4358: permu 莫队算法
		
[题意]给定长度为n的排列,m次询问区间[L,R]的最长连续值域.n<=50000. [算法]莫队算法 [题解]考虑莫队维护增加一个数的信息:设up[x]表示数值x往上延伸的最大长度,down[ ...
 - bzoj 4358: permu  莫队
		
第一步先莫队分块. 对于每一块l~r,初始右端点设为r+1,然后每个询问先将右端点往右移,然后处理询问在l~r之间的部分,最后用一个栈再把l~r的复原. 具体来说是维护两个数组now1和now2,一个 ...
 - BZOJ 3757 苹果树 ——莫队算法
		
挺好的一道题目,怎么就没有版权了呢?大数据拍过了,精神AC.... 发现几种颜色这性质比较垃圾,不可加,莫队硬上. %了一发popoqqq大神的博客, 看了一波VFK关于糖果公园的博客, 又找了wjm ...
 - bzoj 2038(莫队算法)
		
2038: [2009国家集训队]小Z的袜子(hose) 时间限制: 20 Sec 内存限制: 259 MB 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来 ...
 - Codeforces 765F Souvenirs - 莫队算法 - 链表 - 线段树
		
题目传送门 神速的列车 光速的列车 声速的列车 题目大意 给定一个长度为$n$的序列,$m$次询问区间$[l, r]$内相差最小的两个数的差的绝对值. Solution 1 Mo's Algorith ...
 - BZOJ 4358 坑 莫队+线段树 死T
		
这是一个坑 竟然卡nsqrt(n)logn T死 等更 //By SiriusRen #include <cmath> #include <cstdio> #include & ...
 - bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)
		
[题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ...
 - bzoj 2038 A-小Z的袜子[hose] - 莫队算法
		
作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从 ...
 - 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法
		
[题意]给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值.n,m<=5*10^4,0<=ai<=10^9. [算法]树分块+ ...
 
随机推荐
- 关于“.bash_profile”和“.bashrc”区别的总结
			
bash的startup文件 Linux shell是用户与Linux系统进行交互的媒介,而bash作为目前Linux系统中最常用的shell,它支持的startup文件也并不单一,甚至容易让人感到费 ...
 - cs231n(三) 误差反向传播
			
摘要 本节将对反向传播进行直观的理解.反向传播是利用链式法则递归计算表达式的梯度的方法.理解反向传播过程及其精妙之处,对于理解.实现.设计和调试神经网络非常关键.反向求导的核心问题是:给定函数 $f( ...
 - HBuilder控制台集成命令提示符(终端/CMD)功能
			
参考:https://jingyan.baidu.com/album/6b97984dc9cda31ca2b0bf00.html?picindex=3
 - python 写入Excel
			
一.安装xlrd模块: 1.mac下打开终端输入命令: pip install XlsxWriter 2.验证安装是否成功: 在mac终端输入 python 进入python环境 然后输入 imp ...
 - Vs code常用插件
			
Vs code常用插件 1.View In Browser 由于 VSCode 没有提供直接在浏览器中打开文件的内置界面,所以此插件在快捷菜单中添加了在默认浏览器查看文件选项,以及在客户端(Firef ...
 - git 设置tracking information
			
There is no tracking information for the current branch.Please specify which branch you want to merg ...
 - Spring-Boot数据库密码加密配置
			
springboot集成mysql/oracle时需要在yml/properties中配置数据库信息,用户名密码是肯定有的,所以就涉及到密码的加密,当然不加密也是可以的,正如某位大佬所说的,不加密就像 ...
 - Gym 101194E / UVALive 7901 - Ice Cream Tower - [数学+long double][2016 EC-Final Problem E]
			
题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...
 - Luogu 1309 - 瑞士轮 - [归并排序]
			
题目链接:https://www.luogu.org/problemnew/show/P1309 题解: 每次比赛前,每个人都是按照分数降序排好的,那么比赛完后,将选手按输赢分成两组,顺序依然按照原顺 ...
 - Luogu 1071 - 潜伏者 - [字符串]
			
题目链接:https://www.luogu.org/problemnew/show/P1071 题解: 模拟就完事儿了. 注意failed的情况有:出现一个 $f[x]$ 对应多个值:存在两个不同的 ...