【BZOJ4358】permu

Description

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

Input

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

Output

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

Sample Input

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

Sample Output

3
3
4

HINT

对于询问[1,4],P2,P4,P1组成最长的值域连续段[1,3];
对于询问[5,8],P8,P5,P7组成最长的值域连续段[4,6];
对于询问[1,7],P5,P7,P3,P6组成最长的值域连续段[5,8]。
1<=n,m<=50000

题解:一开始想莫队没想出来,然后就去膜拜了Claris的题解

然后下传标记的时候又有些不明白,于是又去膜拜了Claris的代码。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=50010;
const int inf=1<<30;
int n,m,X,rt,D;
int p[maxn],v[maxn],ans[maxn];
struct kd
{
int v[2],sm[2],sn[2],ls,rs,ts,val,tt,org,ht,hs,hv;
kd () {}
kd (int a,int b){v[0]=sm[0]=sn[0]=a,v[1]=sm[1]=sn[1]=b,ls=rs=ts=val=hs=hv=0,tt=ht=-inf;}
}t[maxn];
bool cmp(const kd &a,const kd &b)
{
return (a.v[D]==b.v[D])?(a.v[D^1]<b.v[D^1]):(a.v[D]<b.v[D]);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void ps(int x,int y)
{
t[x].val+=y;
if(t[x].val>t[x].hv) t[x].hv=t[x].val;
if(t[x].tt>=0)
{
t[x].tt+=y;
if(t[x].tt>t[x].ht) t[x].ht=t[x].tt;
}
else
{
t[x].ts+=y;
if(t[x].ts>t[x].hs) t[x].hs=t[x].ts;
}
}
void pt(int x,int y)
{
t[x].val=y;
if(t[x].val>t[x].hv) t[x].hv=t[x].val;
t[x].tt=y,t[x].ts=0;
if(t[x].tt>t[x].ht) t[x].ht=t[x].tt;
}
void phs(int x,int y)
{
t[x].hv=max(t[x].hv,t[x].val+y);
if(t[x].ht>=0) t[x].ht=max(t[x].ht,t[x].tt+y);
else t[x].hs=max(t[x].hs,t[x].ts+y);
}
void pht(int x,int y)
{
t[x].hv=max(t[x].hv,y);
t[x].ht=max(t[x].ht,y);
}
void pushup(int x,int y)
{
t[x].sm[0]=max(t[x].sm[0],t[y].sm[0]);
t[x].sm[1]=max(t[x].sm[1],t[y].sm[1]);
t[x].sn[0]=min(t[x].sn[0],t[y].sn[0]);
t[x].sn[1]=min(t[x].sn[1],t[y].sn[1]);
}
void pushdown(int x)
{
if(t[x].hs)
{
if(t[x].ls) phs(t[x].ls,t[x].hs);
if(t[x].rs) phs(t[x].rs,t[x].hs);
t[x].hs=0;
}
if(t[x].ht>=0)
{
if(t[x].ls) pht(t[x].ls,t[x].ht);
if(t[x].rs) pht(t[x].rs,t[x].ht);
t[x].ht=-inf;
}
if(t[x].ts)
{
if(t[x].ls) ps(t[x].ls,t[x].ts);
if(t[x].rs) ps(t[x].rs,t[x].ts);
t[x].ts=0;
}
if(t[x].tt>=0)
{
if(t[x].ls) pt(t[x].ls,t[x].tt);
if(t[x].rs) pt(t[x].rs,t[x].tt);
t[x].tt=-inf;
}
}
int build(int l,int r,int d)
{
if(l>r) return 0;
int mid=(l+r)>>1;
D=d,nth_element(t+l,t+mid,t+r+1,cmp);
t[mid].ls=build(l,mid-1,d^1),t[mid].rs=build(mid+1,r,d^1);
if(t[mid].ls) pushup(mid,t[mid].ls);
if(t[mid].rs) pushup(mid,t[mid].rs);
return mid;
}
void updata(int x)
{
if(!x) return;
if(t[x].sn[0]>X||t[x].sm[1]<X)
{
pt(x,0);
return ;
}
if(t[x].sm[0]<=X&&t[x].sn[1]>=X)
{
ps(x,1);
return ;
}
pushdown(x);
if(t[x].v[0]<=X&&t[x].v[1]>=X) t[x].val++,t[x].hv=max(t[x].hv,t[x].val);
else t[x].val=0;
updata(t[x].ls),updata(t[x].rs);
}
void dfs(int x)
{
if(!x) return ;
pushdown(x),ans[t[x].org]=t[x].hv;
dfs(t[x].ls),dfs(t[x].rs);
}
int main()
{
n=rd(),m=rd();
int i,a,b;
for(i=1;i<=n;i++) p[rd()]=i;
for(i=1;i<=m;i++) a=rd(),b=rd(),t[i]=kd(a,b),t[i].org=i;
rt=build(1,m,0);
for(i=1;i<=n;i++)
X=p[i],updata(rt);
dfs(rt);
for(i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}

【BZOJ4358】permu kd-tree的更多相关文章

  1. 【数据结构】B-Tree, B+Tree, B*树介绍 转

    [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...

  2. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  3. LG3690 【模板】Link Cut Tree (动态树)

    题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...

  4. AC日记——【模板】Link Cut Tree 洛谷 P3690

    [模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...

  5. LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测

    UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...

  6. (RE) luogu P3690 【模板】Link Cut Tree

    二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...

  7. LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

    P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...

  8. 【LeetCode】199. Binary Tree Right Side View 解题报告(Python)

    [LeetCode]199. Binary Tree Right Side View 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/probl ...

  9. 【数据结构】B-Tree, B+Tree, B*树介绍

    [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tree索引,InnoDB还支持B+Tree索引,Memory ...

随机推荐

  1. NFS 服务配置篇

    安装.配置NFS服务 1.NFS简介 NFS(network file system) NFS是一个主机A通过网络,允许其他主机B可以来共享主机A的一个目录文件的一个文件系统 2.需要安装两个包nfs ...

  2. My97DatePicker控件显示时分秒

    方式一: if (!WebCalendar.timeShow) WebCalendar.dateReg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/; else ...

  3. ASP.NET MVC学习---(六)CRUD例子补充

    在之前,我们使用mvc做了一个crud的小例子 整个项目过程应该是能够很容易理解的 通过这个例子我们可以大概的了解mvc的基本使用方法 但是由于篇幅限制(还不如说自己懒不想写那么长...) 没有能够在 ...

  4. Effective C++ 条款17

    以独立语句将newed对象置入智能指针 本节我们须要学习的知识核心是注意编译器在同一语句中,调用次序具有不确定性,不同语句中,调用次序确定. 上面的话什么意思? 请看下面代码: int priorit ...

  5. 可移动磁盘显示0kb打不开怎么办

      移动硬盘.U盘打不开怎么办 为了方便共享,大多数人都购买了移动硬盘.那么如果有一天,发现移动硬盘打不开了,怎么办?下面为大家介绍移动硬盘打不开的解决方法. 未格式化故障 第一步:双击盘符出现未格式 ...

  6. js:获得时间

    <script type="text/javascript"> function bodyLoad() { var dateTime = new Date(); var ...

  7. 事务(Transaction)概念和特性

    http://baike.baidu.com/view/121511.htm 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库 ...

  8. flex-direction用法解释

    语法: flex-direction:row | row-reverse | column | column-reverse 默认值:row 适用于:flex容器 继承性:无 动画性:否 计算值:指定 ...

  9. 1 android 人脸识别

    1 https://www.google.com.hk/search?newwindow=1&safe=strict&q=android+%E5%9B%BE%E7%89%87%E4%B ...

  10. android性能优化学习笔记(加快应用程序启动速度:)

    一:安卓中应用程序的启动方式有两种: 冷启动:后台没有该应用进程,系统会重新创建一个进程分配给该应用(所以会先创建和初始化Application类,再创建和初始化MainActivity,包括测量,布 ...