题目

刚开始并没有看懂题意于是痛苦的挣扎了好久

题意是这样的

问\([l,r]\)有多少对\((i,j)\)满足\(a_i\)和\(a_j\)恰好是\(a_i...a_j\)中严格最大的两个数

强制在线

先考虑\(a_j\)是\(a_i...a_j\)严格第二大的那一个

我们可以一个单调栈扫过去找到\(j\)之前第一个大于等于\(a_j\)的,这个位置就是我们要找的\(i\)了

再考虑\(a_j\)是\(a_i...a_j\)最大的那一个

显然如果\(i\)满足\(i<j\)且\(a_j\)是\(a_i\)右边第一个满足\(a_j>=a_i\)的元素就好了

这样的话最终答案显然是\(n\)级别的,不会太大,于是直接用单调栈把这些区间都找出来,每次询问\([l,r]\)完全包含了多个这样的区间就好了

主席树就可以实现

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<set>
#define mp std::make_pair
#define maxn 300005
#define M maxn*42
#define lowbit(x) ((x)&(-x))
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
typedef std::pair<int,int> pii;
std::set<pii> s;
int n,m,q,cnt;
int st[maxn],top,last,rt[maxn];
int a[maxn],L[maxn],R[maxn];
std::vector<int> v[maxn];
int l[M],r[M],d[M];
int change(int pre,int x,int y,int pos)
{
int root=++cnt;
d[root]=d[pre]+1;
if(x==y) return root;
l[root]=l[pre],r[root]=r[pre];
int mid=x+y>>1;
if(pos<=mid) l[root]=change(l[pre],x,mid,pos);
else r[root]=change(r[pre],mid+1,y,pos);
return root;
}
int query(int p1,int p2,int x,int y,int k)
{
if(x==y) return d[p2]-d[p1];
int mid=x+y>>1;
if(k<=mid) return query(l[p1],l[p2],x,mid,k)+d[r[p2]]-d[r[p1]];
return query(r[p1],r[p2],mid+1,y,k);
}
int main()
{
n=read(),m=read(),q=read();
for(re int i=1;i<=n;i++) a[i]=read();
for(re int i=n;i;--i)
{
while(top&&a[st[top]]<=a[i]) L[st[top--]]=i;
st[++top]=i;
}
top=0;
for(re int i=1;i<=n;i++)
{
while(top&&a[st[top]]<=a[i]) R[st[top--]]=i;
st[++top]=i;
}
for(re int i=1;i<=n;i++) if(L[i]) s.insert(mp(L[i],i));
for(re int i=1;i<=n;i++) if(R[i]) s.insert(mp(i,R[i]));
for(std::set<pii>::iterator i=s.begin();i!=s.end();++i)
{
pii t=*i;
v[t.second].push_back(t.first);
}
for(re int i=1;i<=n;i++)
{
int now=rt[i-1];
for(re int j=0;j<v[i].size();j++) now=change(now,1,n,v[i][j]);
rt[i]=now;
}
int x,y;
while(m--)
{
x=read(),y=read();
if(q) x=(x+last-1)%n,y=(y+last-1)%n,x++,y++;
if(x>y) std::swap(x,y);
if(x==y) last=0;
else last=query(rt[x-1],rt[y],1,n,x);
printf("%d\n",last);
}
return 0;
}

「bzoj3956: Count」的更多相关文章

  1. 「C语言」文件的概念与简单数据流的读写函数

    写完「C语言」单链表/双向链表的建立/遍历/插入/删除 后,如何将内存中的链表信息及时的保存到文件中,又能够及时的从文件中读取出来进行处理,便需要用到”文件“的相关知识点进行文件的输入.输出. 其实, ...

  2. FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...

  3. 「THUWC 2017」随机二分图

    「THUWC 2017」随机二分图 解题思路 : 首先有一个 \(40pts\) 的做法: 前 \(20pts\) 暴力枚举最终的匹配是怎样的,check一下计算方案数,后 \(20pts\) 令 \ ...

  4. loj #2510. 「AHOI / HNOI2018」道路

    #2510. 「AHOI / HNOI2018」道路 题目描述 W 国的交通呈一棵树的形状.W 国一共有 n−1 个城市和 nnn 个乡村,其中城市从 111 到 n−1 编号,乡村从 111 到 n ...

  5. loj #2509. 「AHOI / HNOI2018」排列

    #2509. 「AHOI / HNOI2018」排列   题目描述 给定 nnn 个整数 a1,a2,…,an(0≤ai≤n),以及 nnn 个整数 w1,w2,…,wn.称 a1,a2,…,an 的 ...

  6. 「面试高频」二叉搜索树&双指针&贪心 算法题指北

    本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...

  7. 【微信小程序】开发实战 之 「视图层」WXML & WXSS 全解析

    在<微信小程序开发实战 之 「配置项」与「逻辑层」>中我们详细阐述了小程序开发的程序和页面各配置项与逻辑层的基础知识.下面我们继续解析小程序开发框架中的「视图层」部分.学习完这两篇文章的基 ...

  8. 「UR#6」懒癌

    「UR#6」懒癌 妈妈我居然看了六个小时题解,快救救乌干达的可怜儿童吧. 接下来开始膜官方题解: ​ 其实就算有上面两个结论也不是很好想到任意复杂度的做法,关键在于要想到一个人是怎么推断自己的狗是不是 ...

  9. [转帖]「日常小记」linux中强大且常用命令:find、grep

    「日常小记」linux中强大且常用命令:find.grep https://zhuanlan.zhihu.com/p/74379265 在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍 ...

随机推荐

  1. element-ui Form表单验证

    element-ui Form表单验证规则全解 element的form表单非常好用,自带了验证规则,用起来很方便,官网给的案例对于一些普通场景完全没问题,不过一些复杂场景的验证还得自己多看文档摸索, ...

  2. (转)详解Linux中SSH远程访问控制

    详解Linux中SSH远程访问控制 原文:http://blog.51cto.com/dengqi/1260038 SSH:是一种安全通道协议,主要用来实现字符界面的远程登录,远程复制等功能(使用TC ...

  3. Guid和Oracle中16进制字符的转换

    我们知道在Oracle中存的guid是16进制字符串,而在我们的C#代码中存的是guid对象,这样我会就要进行转换, 下面给出了两者进行转换的方法: public class Guid2RawProc ...

  4. 【Linux】time+dd测试硬盘读写速度

    dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. dd 命令通用语法格式如下: dd if=path/to/input_file ...

  5. 20个最受欢迎的Linux命令(转)

    本文根据 commandlinefu 网站的历史排名,筛选出了前 20 个得票最高的 Linux 命令.看看你都能熟练使用了吗? 1.以 root 帐户执行上一条命令 sudo !! 2.利用 Pyt ...

  6. css三角块

    html: <div class="angle"></div> css: .angle{ width: 0px; height: 0px; border-b ...

  7. 归并排序——Java实现

    一.排序思想 将两个或两个以上的一排序文件合并成一个有序文件的过程叫归并,而归并排序就是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用.将以有序的了序列合并,得到完全有序 ...

  8. 4.kafka的安装部署

    为了安装过程对一些参数的理解,我先在这里提一下kafka一些重点概念,topic,broker,producer,consumer,message,partition,依赖于zookeeper, ka ...

  9. js正则验证表达式

    //上传文件大小验证 $.fn.checkFileTypeAndSize = function (options) { //默认设置 var defaults = { allowedExtension ...

  10. Mybatis generator 逆向生成代码

    Mybatis generator 逆向生成代码 简单介绍 本文介绍用mybatis逆向生成javaben dao接口 1.创建maven项目 创建相应的包 附上项目创建完成的图片 然后在pom.xm ...