问题: permu

时间限制: 30 Sec  内存限制: 512 MB

题面


题目描述

给出一个长度为n的排列P(P1,P2,...Pn),以及m个询问。每次询问某个区间[l,r]中,最长的值域

连续段长度。

输入格式

第一行两个整数n,m。

接下来一行n个整数,描述P。

接下来m行,每行两个整数l,r,描述一组询问。

输出格式

对于每组询问,输出一行一个整数,描述答案。

样例输入

8 3
3 1 7 2 5 8 6 4
1 4
5 8
1 7

样例输出

3
3
4

题解


线段树+莫队。

考虑维护区间连续值域长度最大值。

首先显然莫队。(毕竟是蒟蒻我在莫队专题里遇到的题目……)

序列操作、多次询问,最关键的是无修!(没学过带修莫队不行啊 /理直气壮)

于是考虑怎么在不同区间内转移。

我们先种一棵值域线段树维护点的存在与否。

我们假设li为某段区间从左边界开始的最长值域连续段,ri为从右边界开始的最长值域连续段,mi为区间中最长值域连续段,考虑如何转移。

当push_up的时候,li由左儿子的li转移而来。特殊地,我们考虑左儿子整个区间连续,则li由左儿子的区间大小加上右儿子的li转移而来。

同理,ri由右儿子的ri转移。特殊情况为右儿子的区间大小加上左儿子的ri。

考虑mi的转移。显然mi由左儿子的mi和右儿子的mi以及左儿子的ri与右儿子的li组成的新区间转移而来。

注意我们开的是值域线段树,因此可以保证区间的连续性。

于是线段树维护3个标记我们就可以方便的进行转移了。

然后就是莫队板子。不断在线段树中插入点,删除点并进行转移统计答案。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define rint register int
using namespace std;
int n,m,a[],tk[],belong[],l,r,sum_q,ans[];
struct node1{int li,ri,mi,size;}t[];
struct node2{int l,r,id;}que[];
inline bool cmp(node2 a,node2 b)
{
return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&)?a.r<b.r:a.r>b.r);
}
inline void build(rint k,rint l,rint r)
{
if(l==r){t[k].size=;return ;}
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
t[k].size=t[k<<].size+t[k<<|].size;
return ;
}
inline void update(rint k)
{
t[k].li=t[k<<].li;t[k].ri=t[k<<|].ri;
if(t[k<<].li==t[k<<].size)t[k].li+=t[k<<|].li;
if(t[k<<|].ri==t[k<<|].size)t[k].ri+=t[k<<].ri;
// cout<<"left:"<<t[k<<1].mi<<" right:"<<t[k<<1|1].mi<<" mid:"<<t[k<<1].ri+t[k<<1|1].li<<endl;
t[k].mi=max(max(t[k<<].mi,t[k<<|].mi),t[k<<].ri+t[k<<|].li);
}
inline void change(rint k,rint p,rint u,rint l,rint r)
{
// cout<<"change:"<<p<<endl;
if(l==u&&r==u)
{
// cout<<p<<endl;
t[k].mi=p;t[k].li=p;t[k].ri=p;
// cout<<"mi:"<<t[k].mi<<endl;
return ;
}
rint mid=(l+r)>>;
if(u<=mid)change(k<<,p,u,l,mid);
else change(k<<|,p,u,mid+,r);
update(k);//cout<<t[k].mi<<endl;
return ;
}
int main()
{
scanf("%d %d",&n,&m);
sum_q=(int)sqrt(n);
for(rint i=;i<=n;++i)
{
scanf("%d",&a[i]);
belong[i]=i/sum_q+;
}
build(,,n);
for(rint i=;i<=m;++i)
{
scanf("%d %d",&que[i].l,&que[i].r);
que[i].id=i;
}
sort(que+,que+m+,cmp);
for(rint i=que[].l;i<=que[].r;++i)
{
tk[a[i]]++;
if(tk[a[i]]==)change(,,a[i],,n);
}
ans[que[].id]=t[].mi;
l=que[].l,r=que[].r;
for(rint i=;i<=m;++i)
{
// cout<<l<<" "<<que[i].l<<endl;
while(l<que[i].l){tk[a[l]]--;if(tk[a[l]]==)change(,,a[l],,n);l++;}
// cout<<l<<" "<<que[i].l<<endl;
while(l>que[i].l){l--;tk[a[l]]++;if(tk[a[l]]==)change(,,a[l],,n);}
while(r<que[i].r){r++;tk[a[r]]++;if(tk[a[r]]==)change(,,a[r],,n);}
while(r>que[i].r){tk[a[r]]--;if(tk[a[r]]==)change(,,a[r],,n);r--;}
ans[que[i].id]=t[].mi;
}
for(rint i=;i<=m;++i)
cout<<ans[i]<<endl;
return ;
}

最开始没设初始区间调了半个小时……

ps:此题需要卡常,最好使用奇偶性排序法QAQ(18000(TLE63)->12000(AC))

「题解」:[BZOJ4358]permu的更多相关文章

  1. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  2. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  3. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  4. 「题解」:[loj2763][JOI2013]现代豪宅

    问题 A: 现代豪宅 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...

  5. 「题解」:$Six$

    问题 A: Six 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...

  6. 「题解」:$Smooth$

    问题 A: Smooth 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...

  7. 「题解」:Kill

    问题 A: Kill 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...

  8. 「题解」:y

    问题 B: y 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...

  9. 「题解」:x

    问题 A: x 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 赛时想到了正解并且对拍了很久.对拍没挂,但是评测姬表示我w0了……一脸懵逼. 不难证明,如果对于两个数字 ...

随机推荐

  1. Delphi中的Sender:TObject对象解析转载

    https://blog.csdn.net/jl_tiny/article/details/24376661 Delphi中的Sender:TObject对象解析 procedure TForm1.B ...

  2. 在html页面引用css文件的方法

    引用CSS文件到Html方法-css引入,css引用 使用不同的方法来引用css样式表,最终到达的效果相同,但是使用不同方法应用的css文件将影响到SEO及网页打开速度效率. html引用css方法如 ...

  3. Victor and String HDU - 5421 双向回文树

    题意: 有n种操作,开始给你一个空串,给你4中操作 1 c  在字符串的首部添加字符c 2 c  在字符串的尾部添加字符c 3  询问字符中的本质不同的回文串的个数 4 询问字符串中回文串的个数 思路 ...

  4. 一点响应式Web设计与实现思路

    摘要: 是否还在为你的应用程序适配PC端,移动端,平板而苦苦思索呢,是否在寻找如何一套代码适配多终端方式呢,是否希望快速上手实现你的跨终端应用程序呢,是的话,那就看过来吧,本文阐述响应式UI设计相关理 ...

  5. java 3des加密问题记录

    3des加密有不同的加密模式和填充模式,这个网上很多不多说了,只要保证加解密的时候加密模式和填充模式保持一致就可以了 首先对于密钥的生成,java中有2种方式: 1.第一种,采用ECB模式和不填充模式 ...

  6. mysql UDF提权 sys_bineval

    介绍: 执行shellcode – sys_bineval sqmapl自带udf.dll中存在函数’sys_bineval,执行shellcode – sys_bineval 利用: MSF生成sh ...

  7. 在VMware中创建一个新的虚拟机 ,安装Linux4.X系统 ,之后在此基础上安装openfiler(网络存储管理实用程序)

    到此为止虚拟机的前期设置准备好了 下面来为此虚拟机添加iso镜像 (这个是在http://www.openfiler.com/community/download  openfiler官网上面下载的) ...

  8. leetcode-421-数组中两个数的最大异或值*(前缀树)

    题目描述: 方法一: class Solution: def findMaximumXOR(self, nums: List[int]) -> int: root = TreeNode(-1) ...

  9. for in循环介绍以及陷阱

    大家都知道在JavaScript中提供了两种方式迭代对象: (1)for 循环: (2)for..in循环: 使用for循环进行迭代数组对象,想必大家都已经司空见惯了.但是,使用for.. in循环时 ...

  10. python实现百度OCR图片识别

    一.直接上代码 import base64 import requests class CodeDemo: def __init__(self,AK,SK,code_url,img_path): se ...