题目传送门

  需要高级权限的传送门

题目大意

  给定一个全排列,询问一个区间内的值域连续的一段的长度的最大值。

  考虑使用莫队算法。

  每次插入一个数$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 - 莫队算法 - 链表的更多相关文章

  1. 【BZOJ】4358: permu 莫队算法

    [题意]给定长度为n的排列,m次询问区间[L,R]的最长连续值域.n<=50000. [算法]莫队算法 [题解]考虑莫队维护增加一个数的信息:设up[x]表示数值x往上延伸的最大长度,down[ ...

  2. bzoj 4358: permu 莫队

    第一步先莫队分块. 对于每一块l~r,初始右端点设为r+1,然后每个询问先将右端点往右移,然后处理询问在l~r之间的部分,最后用一个栈再把l~r的复原. 具体来说是维护两个数组now1和now2,一个 ...

  3. BZOJ 3757 苹果树 ——莫队算法

    挺好的一道题目,怎么就没有版权了呢?大数据拍过了,精神AC.... 发现几种颜色这性质比较垃圾,不可加,莫队硬上. %了一发popoqqq大神的博客, 看了一波VFK关于糖果公园的博客, 又找了wjm ...

  4. bzoj 2038(莫队算法)

    2038: [2009国家集训队]小Z的袜子(hose) 时间限制: 20 Sec  内存限制: 259 MB 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来 ...

  5. Codeforces 765F Souvenirs - 莫队算法 - 链表 - 线段树

    题目传送门 神速的列车 光速的列车 声速的列车 题目大意 给定一个长度为$n$的序列,$m$次询问区间$[l, r]$内相差最小的两个数的差的绝对值. Solution 1 Mo's Algorith ...

  6. BZOJ 4358 坑 莫队+线段树 死T

    这是一个坑 竟然卡nsqrt(n)logn T死 等更 //By SiriusRen #include <cmath> #include <cstdio> #include & ...

  7. bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)

    [题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ...

  8. bzoj 2038 A-小Z的袜子[hose] - 莫队算法

    作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从 ...

  9. 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法

    [题意]给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值.n,m<=5*10^4,0<=ai<=10^9. [算法]树分块+ ...

随机推荐

  1. IOS gallery

    https://github.com/mengxianliang/XLCardSwitch

  2. [LeetCode] Group Anagrams 群组错位词

    Given an array of strings, group anagrams together. Example: Input: ["eat", "tea" ...

  3. Eclipse的设置、调优、使用(解决启动卡顿等问题)----转

    eclipse调优 一般在不对eclipse进行相关设置的时候,使用eclipse总是会觉得启动好慢,用起来好卡,其实只要对eclipse的相关参数进行一些配置,就会有很大的改善. 加快启动速度 1. ...

  4. 19、AJAX

    1.Ajax的概念 Ajax是一种在无需重新加载整个网页(刷新页面)的情况下,能够更新部分网页的技术. Ajax的全称是AsynchronousJavaScript and XML,即异步JavaSc ...

  5. 【C++ mid-term exerises】

    1. 用掷骰子方式,模拟班级每个学号被随机抽点的概率. (12分) 具体要求如下: (1)设计并实现一个骰子类Dice. ① 数据成员sides表示骰子面数.构造时,指定骰子是6面,8面,还是其它数值 ...

  6. ffmpeg快速获取视频截图

    使用ffmpeg可以非常方便的生成视频截图,命令行下的mplayer也可以做视频截图,只不过mplayer在本质上还是调用ffmpeg来实现.ffmpeg 通过指定 -vcodec 参数为 mjpeg ...

  7. 转CB大佬的几个有用的MySQL知识

    1.find_in_set函数 find_in_set(str,strlist); str是一个字符串 strlist是字符串列表--一个有多个子链被“,”分开的字符串 有多种情况: a.str为nu ...

  8. vue的属性样式绑定,

    <template> <div id="app"> <div v-html="H"></div>  //绑定ht ...

  9. Fiddler (进阶)内置命令与断点

    Fiddler 内置命令与断点 命令 对应请求项 介绍 示例 ? All 问号后边跟一个字符串,可以匹配出包含这个字符串的请求 ?google > Body 大于号后面跟一个数字,可以匹配出请求 ...

  10. luogu3978 [TJOI2015]概率论

    题目链接:洛谷 题目大意:求所有$n$个点的有根二叉树的叶子节点数总和/$n$个点的有根二叉树的个数. 数据范围:$n\leq 10^9$ 生成函数神题!!!!(我只是来水博客的) 首先$n$个点的有 ...