Description

       多年之后,worldwideD厌倦竞争,隐居山林。
       他的家乡开始发展起了旅游业,在一条很长的主干道上,有N个旅游景点,按顺序编号为1到N。根据游客们网上的评分,第i个景点有一个评估值a[i],为了区分开不同的景点,评估值是两两不同的。
       今天有M组游客前来旅游,第i组游客选择遍历景点Li到景点Ri这一段路。他们搜到Li到Ri的所有评估值,如果对于景点j(Li≤j≤Ri),不存在景点x(Li≤x<j)满足a[x]>a[j]或不存在景点y(j<y≤Ri)满足a[y]>a[j],那么他们会进入景点j。
       现在worldwideD想知道,每组游客会去多少个景点。
 

Input

第一行两个整数N,M,意义见题面。
接下来一行N个整数,第i个是a[i],意义见题面。
接下来M行,第i行两个整数Li,Ri,意义见题目。

Output

M行,第i行表示第i组游客去的景点个数。
 

Sample Input

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

Sample Output

3
3
4
3
 

Data Constraint

30%:N,M≤5,000
60%:N,M≤100,000
100%:N,M≤1,000,000   0≤|a[i]|≤1,000,000,000  1≤Li≤Ri≤N
 

Hint

第一组游客选择路段的景点评估值序列为[3,1,7,4,5],其中3,7,5满足条件
第二组游客选择路段的景点评估值序列为[1,7,4,5],其中1,7,5满足条件
第三组游客选择路段的景点评估值序列为[1,7,4,5,2],其中3,7,5,2满足条件
第四组游客选择路段的景点评估值序列为[4,5,2],其中4,5,2满足条件
本题数据规模较大,请注意您的常数造成的影响。
在这里给出一种输入输出优化的模板,在主程序中直接调用read()即可读入一个整数,调用write(x)可以把一个int变量x输出并换行。
int read()
{
       int x=0,sig=1;
       char c;
       for (c=getchar();c<'0' || c>'9';c=getchar()) if (c=='-') sig=-1;
       for (;c>='0' && c<='9';c=getchar()) x=x*10+c-48;
       return x*sig;
}
void write(int x)
{
       if (!x) putchar('0');else
       {
              char s[10];
              int i,j=0;
              for (;x>0;x/=10) s[j++]=x%10;
              for (i=j-1;i>=0;i--) putchar(s[i]+48);
       }
       putchar('\n');
}

考虑30分的可以拿个单调栈向左扫一遍向右扫一遍再将个数加起来再减去1即可。

这道题是要求我们判断这个景点的评估值在给定的子区间里是否有比它大值存在,如果一边没有大于它的存在,则它就是旅客会前往的景点。

既需要位置关系又需要大小关系,我们考虑大根笛卡尔树。

笛卡尔树是一种同时满足二叉搜索树和堆的性质的数据结构。

它的中序遍历的序列为原数组序列。

树中节点的值大于其左右子节点的值。

建树很简单, 用个单调栈O(n)即可建好。我们很容易发现一些性质:

1.对于一个询问L,R它的答案只会出现在笛卡尔树的路径上。

2.L,R的LCA中,从L到LCA路径上,有一个点是其父亲的左孩子答案就加一,R到LCA上,有一个点是其父亲的右孩子答案就加一。

我们知道笛卡尔树上一个点A是其父亲B的左孩子表明A在它父亲B的左边,且权值小于父亲B,对于LLCA路径(也就是区间L-LCA)中而言这意味着A的左边没有比它大的点(如果有,那么A应该会在比它大的那个点C的右边),于是就对答案有1的贡献,虽然右边有比它大的点(父亲B);对于RLCA路径(也就是区间LCA-R)中则相反。这就很好的符合题目的性质,我们就可以用笛卡尔树解决这道题了。

我们就可以用tarjan求出LCA,然后预处理下每个点到根节点的路径上有多少个点是其父亲的左孩子和右孩子,然后计算出答案即可。时间复杂度 O(NαN)

 #include<iostream>
#include<cstring>
#include<cstdio>
#define N 3000002
using namespace std;
int n,m,t,zhan[N],len,num,ans[N],f[N],u,v,head[N],root,visit[N];
struct data1{
int l,r,p,v,lnum,rnum;
void init(){
l=,r=,p=,v=,lnum=,rnum=;
}
}tree[N];
struct data2{
int next,to,sign;
}line[N];
int read()
{
int x=,sig=;
char c;
for (c=getchar();c<'' || c>'';c=getchar()) if (c=='-') sig=-;
for (;c>='' && c<='';c=getchar()) x=x*+c-;
return x*sig;
}
void write(int x)
{
if (!x) putchar('');else
{
char s[];
int i,j=;
for (;x>;x/=) s[j++]=x%;
for (i=j-;i>=;i--) putchar(s[i]+);
}
putchar('\n');
}
void add(int u,int v){
num++;
line[num].next=head[u];
line[num].to=v;
line[num].sign=num;
head[u]=num;
num++;
line[num].next=head[v];
line[num].to=u;
line[num].sign=num;
head[v]=num;
}
int build(){ //建笛卡尔树
len=;
zhan[]=;
for (int i=;i<=n;i++){
while ((len>)&&(tree[zhan[len]].v<tree[i].v)) len--;
if (len){
tree[i].p=zhan[len];
tree[tree[zhan[len]].r].p=i;
tree[i].l=tree[zhan[len]].r;
tree[zhan[len]].r=i;
}
else {
tree[zhan[]].p=i;
tree[i].l=zhan[];
}
zhan[++len]=i;
}
return zhan[];
}
int find(int x){
if (f[x]==x) return x;
f[x]=find(f[x]);
return f[x];
}
void tarjan(int x,int ln,int rn){ //Tarjan求LCA
f[x]=x;
visit[x]=;
tree[x].lnum=ln;
tree[x].rnum=rn;
if (tree[x].l) {
tarjan(tree[x].l,ln+,rn);
f[tree[x].l]=x;
}
if (tree[x].r) {
tarjan(tree[x].r,ln,rn+);
f[tree[x].r]=x;
}
int v=,e=;
for (int i=head[x];i!=;i=line[i].next){
v=line[i].to;
if (visit[v]){e=find(v);
if (line[i].sign&) ans[(line[i].sign+)/]=tree[x].lnum-tree[e].lnum+tree[v].rnum-tree[e].rnum+;
else ans[line[i].sign/]=tree[v].lnum-tree[e].lnum+tree[x].rnum-tree[e].rnum+;
}
}
}
int main(){
freopen("trip.in","r",stdin);
freopen("trip.out","w",stdout);
memset(visit,,sizeof(visit));
n=read();
m=read();
for (int i=;i<=n;i++){
tree[i].init();
tree[i].v=read();
}
root=build();
num=;
for (int i=;i<=m;i++){
u=read();
v=read();
add(u,v);
}
tarjan(root,,);
for (int i=;i<=m;i++)
write(ans[i]);
return ;
}

神奇的代码

联想很重要

JZOJ.5246【NOIP2017模拟8.8】Trip的更多相关文章

  1. [jzoj 5343] [NOIP2017模拟9.3A组] 健美猫 解题报告 (差分)

    题目链接: http://172.16.0.132/senior/#main/show/5343 题目: 题解: 记旋转i次之后的答案为$ans_i$,分别考虑每个元素对ans数组的贡献 若$s_i& ...

  2. JZOJ 5246. 【NOIP2017模拟8.8A组】Trip(trip)

    5246. [NOIP2017模拟8.8A组]Trip(trip) (File IO): input:trip.in output:trip.out Time Limits: 1500 ms Memo ...

  3. JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠

    JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...

  4. JZOJ 5235. 【NOIP2017模拟8.7A组】好的排列

    5235. [NOIP2017模拟8.7A组]好的排列 (File IO): input:permutation.in output:permutation.out Time Limits: 1000 ...

  5. JZOJ 5236. 【NOIP2017模拟8.7A组】利普希茨

    5236. [NOIP2017模拟8.7A组]利普希茨 (File IO): input:lipschitz.in output:lipschitz.out Time Limits: 1000 ms ...

  6. JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计

    5230. [NOIP2017模拟A组模拟8.5]队伍统计 (File IO): input:count.in output:count.out Time Limits: 1500 ms Memory ...

  7. JZOJ【NOIP2013模拟联考14】隐藏指令

    JZOJ[NOIP2013模拟联考14]隐藏指令 题目 Description 在d维欧几里得空间中,指令是一个长度为2N的串.串的每一个元素为d个正交基的方向及反方向之一.例如,d = 1时(数轴) ...

  8. JZOJ.5281【NOIP2017模拟8.15】钦点

    Description

  9. [jzoj 5178] [NOIP2017提高组模拟6.28] So many prefix? 解题报告(KMP+DP)

    题目链接: https://jzoj.net/senior/#main/show/5178 题目: 题解: 我们定义$f[pos]$表示以位置pos为后缀的字符串对答案的贡献,答案就是$\sum_{i ...

随机推荐

  1. Spring MVC 单元测试异常 Caused by: org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file

    Sping 3.2.8.RELEASE + sping mvc + JDK 1.8运行异常. java.lang.IllegalStateException: Failed to load Appli ...

  2. j2ee高并发时使用全局变量需要注意的问题

    原文:https://blog.csdn.net/jston_learn/article/details/21617311 开发中,全局变量的使用很频繁,但对于多线程的访问,使用全局变量需要注意的地方 ...

  3. 学会Git玩转Github笔记(三)—— Github Pages 搭建个人网站

    https://help.github.com/categories/github-pages-basics/ 一.个人站点 访问 https://用户名.github.io 搭建步骤 1) 创建个人 ...

  4. linux sudo命令详解

    --sudo命令重启网卡 sudo service network restart http://bestchenwu.iteye.com/blog/1450292

  5. ajax 参数data问题 data中的 参数名 参数值为string 提交到后台后,会自动转换参数名相同的 类型 和 js字符串拼接

    latlng"14.6005238,100.43635419999998"Cusid"accb5c1b-6aef-4f3b-a4eb-d60ea1ca5f54" ...

  6. 浅析C#中 ConcurrentDictionary的实现

    简单画了一张图 (灵魂画手 →_→) 如图 ConcurrentDictionary 其中有个tables 对象主要存储,而这个 tables 是一个 很多区块的 数组 ,每个区块 又是一个node的 ...

  7. 由上而下层层剖析细说PCI+ExpresS+11新版精髓

    https://wenku.baidu.com/view/9a16c41fa300a6c30c229f87.html

  8. python学习之urlparse()

    urlparse(url, scheme='', allow_fragments=True) <scheme>://<netloc>/<path>;<para ...

  9. Oracle之批量生成数据

    一.引言 由于测试程序,需要大量的数据 二.方法 1.pl/sql的Generate Data,在tool菜单中可以找到,但是我这里不能用,老是出现错误,应该是软件的原因,但是没找到解决办法,如下图: ...

  10. 如何使用Photoshop(PS)将图片的底色变为透明

    很多时候需要将一张图片的底色变得透明.本文描述了使用PS将图片的一部分变得透明的方法.本例将一段艺术字的背景去掉,将背景透明的文字单独保存成图片,这样以后将这段文字粘贴到其他素材上的时候,就不用担心它 ...