先放代码 晚上补(争取)


[BZOJ4358]permu 线段树+莫队做法

序列操作,多次询问,无修,标准的莫队。

在如何在不同区间内转移的问题上,我选择用线段树来维护(没听xfg讲回滚莫队不行啊)

其中,\(lm\)为一段序列左边界开始最长值域连续段,\(rm\)为右边界开始的,\(mm\)为整个区间中最长值域连续段。

类似于山 海 经,\(pushup\)更新时,左仍为左,右仍为右;当左子区间的\(lm==len\),也就是左子区间全部连续时,这时原区间的\(lm=\)左子区间全部\(+\)右子区间的\(lm\);右边同理。

对于\(mm\),来源是左右子区间的\(mm\)和左子区间的\(rm\)与右子区间的\(lm\)的和的最大值。

因为我们开的是线段树,所以可以保证区间的连续性。

然后按上莫队板子就结束啦。

code:

#include<bits/stdc++.h>
#define fo(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
typedef long long ll;
using namespace std;
inline int qr()
{
char ch=getchar();int x=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
return x*f;
}
#define qr qr()
const int Ratio=0;
const int N=100005;
const int maxi=INT_MAX;
int n,m;
int sq,c[N],bl[N],ans[N],sj[N];
struct rmm
{
int l,r,id;
}q[N];
bool cmp(rmm a,rmm b)
{
if(bl[a.l]!=bl[b.l])
return bl[a.l]<bl[b.l];
if(bl[a.l]&1)
return a.r<b.r;
return a.r>b.r;
}
struct rmmm
{
int len,lm,rm,mm;
}t[N<<2];
namespace Acheron
{
#define lid (rt<<1)
#define rid (rt<<1|1)
void Apushup(int rt)
{
t[rt].lm=t[lid].lm;
t[rt].rm=t[rid].rm;
if(t[lid].lm==t[lid].len)
t[rt].lm+=t[rid].lm;
if(t[rid].rm==t[rid].len)
t[rt].rm+=t[lid].rm;
t[rt].mm=max({t[lid].mm,t[rid].mm,t[lid].rm+t[rid].lm});
}
void Abuild(int rt,int l,int r)
{
if(l==r)
{
t[rt].len=1;
return;
}
int mid=(l+r)>>1;
Abuild(lid,l,mid);
Abuild(rid,mid+1,r);
t[rt].len=t[lid].len+t[rid].len;
return;
}
void Aadd(int rt,int l,int r,int x)
{
if(l==x&&r==x)
{
t[rt].lm=t[rt].rm=t[rt].mm=1;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
Aadd(lid,l,mid,x);
else
Aadd(rid,mid+1,r,x);
Apushup(rt);
return;
}
void Adel(int rt,int l,int r,int x)
{
if(l==x&&r==x)
{
t[rt].lm=t[rt].rm=t[rt].mm=0;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
Adel(lid,l,mid,x);
else
Adel(rid,mid+1,r,x);
Apushup(rt);
return;
}
}
int main()
{
n=qr,m=qr;
sq=sqrt(n);
fo(i,1,n)
c[i]=qr,bl[i]=(i-1)/sq+1;
Acheron::Abuild(1,1,n);
fo(i,1,m)
q[i].l=qr,q[i].r=qr,q[i].id=i;
sort(q+1,q+1+m,cmp);
// Acheron::Abuild(1,1,n);
fo(i,q[1].l,q[1].r)
{
sj[c[i]]++;
Acheron::Aadd(1,1,n,c[i]);
}
ans[q[1].id]=t[1].mm;
int ls=q[1].l,rs=q[1].r;
fo(i,2,m)
{
while(ls>q[i].l)
{
ls--,sj[c[ls]]++;
if(sj[c[ls]]==1)
Acheron::Aadd(1,1,n,c[ls]);
}
while(ls<q[i].l)
{
sj[c[ls]]--;
if(sj[c[ls]]==0)
Acheron::Adel(1,1,n,c[ls]);
ls++;
}
while(rs<q[i].r)
{
rs++,sj[c[rs]]++;
if(sj[c[rs]]==1)
Acheron::Aadd(1,1,n,c[rs]);
}
while(rs>q[i].r)
{
sj[c[rs]]--;
if(sj[c[rs]]==0)
Acheron::Adel(1,1,n,c[rs]);
rs--;
}
ans[q[i].id]=t[1].mm;
}
fo(i,1,m)
printf("%d\n",ans[i]);
return Ratio;
}
苍龙濯世


Updated On 4.23 更新了做法名称。

[BZOJ4358]permu线段树+莫队的更多相关文章

  1. [BZOJ4358]Permu(回滚莫队)

    [BZOJ4358]Permu(回滚莫队) 题面 给出一个长度为n的排列P(P1,P2,...Pn),以及m个询问.每次询问某个区间[l,r]中,最长的值域连续段长度. 分析 最简单的方法显然是用线段 ...

  2. 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队

    看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...

  3. 洛谷P3567 KUR-Couriers [POI2014] 主席树/莫队

    正解:主席树/莫队 解题报告: 传送门! 这题好像就是个主席树板子题的样子,,,? 毕竟,主席树的最基本的功能就是,维护一段区间内某个数字的个数 但是毕竟是刚get到主席树,然后之前做的一直是第k大, ...

  4. 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块

    [题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...

  5. [BZOJ3236][AHOI2013]作业:树套树/莫队+分块

    分析 第一问随便搞,直接说第二问. 令原数列为\(seq\),\(pre_i\)为\(seq_i\)这个值上一个出现的位置,于是可以简化询问条件为: \(l \leq i \leq r\) \(a \ ...

  6. P3180-[HAOI2016]地图【圆方树,莫队,分块】

    正题 题目链接:https://www.luogu.com.cn/problem/P3180 题目大意 \(n\)个点\(m\)条边的一个仙人掌,有点权. \(Q\)次询问给出\(op,x,y\),封 ...

  7. 「题解」:[BZOJ4358]permu

    问题: permu 时间限制: 30 Sec  内存限制: 512 MB 题面 题目描述 给出一个长度为n的排列P(P1,P2,...Pn),以及m个询问.每次询问某个区间[l,r]中,最长的值域 连 ...

  8. 【SDOI2009】HH的项链 (莫队)

    题面 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的 ...

  9. HDU - 2665 Kth number 主席树/可持久化权值线段树

    题意 给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个 题解: 写法很多,主席树是最常用的一种之一 除此之外有:划分树,莫队分块,平衡树等 主席树的定义其实挺模糊, 一般认为就是可持久 ...

  10. Tree and Queries CodeForces - 375D 树上莫队

    http://codeforces.com/problemset/problem/375/D 树莫队就是把树用dfs序变成线性的数组. (原数组要根据dfs的顺序来变化) 然后和莫队一样的区间询问. ...

随机推荐

  1. #树形dp,直径#51nod 1812 树的双直径

    题目 给定一棵树,边权是整数 \(c_i\) ,找出两条不相交的链(没有公共点), 使得链长的乘积最大(链长定义为这条链上所有边的权值之和,如果这条链只有1个点则链长视为0). \(n\leq 4*1 ...

  2. OpenHarmony应用开发之自定义弹窗

     本文转载自<OpenHarmony应用开发之自定义弹窗>,作者:zhushangyuan_ 应用场景 在应用的使用和开发中,弹窗是一个很常见的场景,自定义弹窗又因为极高的自由度得以广泛应 ...

  3. 活动报名|OpenHarmony 战“码”先锋,PR 征集令

    OpenAtom OpenHarmony(以下简称"OpenHarmony")工作委员会首度发起「OpenHarmony 开源贡献者计划」,旨在鼓励开发者参与 OpenHarmon ...

  4. css实现带背景颜色的小三角

    <div id="first"> <p>带背景颜色的小三角实现是比较简单的</p> <span id="top"> ...

  5. ssm 创建bean的三种方式和spring依赖注入的三种方式

    <!--创建bean的第一种方式:使用默认无参构造函数 在默认情况下: 它会根据默认无参构造函数来创建类对象.如果 bean 中没有默认无参构造函数,将会创建失败--> <bean ...

  6. HuffmanTree,哈夫曼树的原理和c++实现

    目录 一.什么是哈夫曼树 二.构造哈夫曼树 三.路径.编码.解码 四.代码 一.什么是哈夫曼树 哈夫曼树又称为最优树. 通过权值来构造树,权值越大,离根节点越近 经常用于无损压缩算法 用于需要优化存储 ...

  7. 大型场景中通过监督视图贡献加权进行多视图人物检测 Multi-View People Detection in Large Scenes via Supervised View-Wise Contribution Weighting

    Multi-View People Detection in Large Scenes via Supervised View-Wise Contribution Weighting 大型场景中通过监 ...

  8. 基于pdfbox实现的pdf添加文字水印工具

    简述 最近有个需求需要给pdf加文字水印,于是开始搜索大法,但是发现网络上的代码基本都是将字体文件直接放在jar包里面.个人强迫症发作(手动狗头),想要像poi一样直接加载系统字体,于是研究了一下午p ...

  9. POJ2251 基础bfs

    题目: 你进入了一个3D的宝藏地宫中探寻宝藏到了宝藏,你可以找到走出地宫的路带出宝藏,或者使用炉石空手回家. 地宫由立方体单位构成,立方体中不定会充满岩石.向上下前后左右移动一个单位需要一分钟.你不能 ...

  10. vue中执行异步函数async和await的用法

    在开发中,可能会遇到两个或多个函数异步执行的情况,对于Vue中函数的异步函数执行做了一个小总结,如下: 异步执行使用async和await完成 created() { this.init() }, m ...