题目传送门

  需要高级权限的传送门

题目大意

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

  考虑使用莫队算法。

  每次插入一个数$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. Springboot中enable注解

    这句话可以作为理解springboot自动注入的原理的钥匙:ImportSelector接口的selectImports返回的数组(类的全类名)都会被纳入到spring容器中. 至于spring怎么根 ...

  2. 【2】static 、construct

    [面向对象] 两个概念: 什么是类 具有一批相同属性的集合 什么是对象 特指的某一个具体的事物 [面向对象的三大特征] 1.封装 public 公共的 protected 受保护的 private 私 ...

  3. 五子棋棋盘布局 table和ul哪个好

    想要在页面布局以上棋盘,可以用ul li 布局,但却有明显的缺点: 1.两行两列:ul li 下面如果再放li 会出错,只能是放其他的,比如div. 或者放li *行*列: 但是这样有两个明显缺陷: ...

  4. 剑指offer——python【第44题】翻转单词顺序

    题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“student ...

  5. 初始easyUI

    1 easyUI布局 <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...

  6. Brocade SAN交换机常用命令

    Brocade SAN交换机常用命令 使用电脑连接Brocade SAN交换机常用命令 使用电脑连接管理网口,默认IP地址为:10.77.77.77,掩码:255.255.255.0 默认用户名:ad ...

  7. Codeforces 584 - A/B/C/D/E - (Done)

    链接:https://codeforces.com/contest/584 A - Olesya and Rodion - [水] 题解:注意到 $t$ 的范围是 $[2,10]$,对于位数小于 $2 ...

  8. en-zh(社会问题)social problems-2

    让屏幕代替父母陪孩子?世卫组织:这样是不对的! No sedentary screen time for babies, WHO says Babies and toddlers should not ...

  9. rebuild online时意外中断 再次重建时报错解决方法

    rebuild online时意外中断 再次重建时报错 SQL> alter index PARTY.IDX_CM_INDIV_CUSTOMER_4 rebuild online; alter ...

  10. 【JVM】-NO.110.JVM.1 -【GC垃圾收集器】

    Style:Mac Series:Java Since:2018-09-10 End:2018-09-10 Total Hours:1 Degree Of Diffculty:5 Degree Of ...