题目描述

输入

输出

样例输入

3 2 0
2 1 2
1 1
1 3

样例输出

0
3


题解

单调栈+可持久化线段树

本题是 bzoj4826 的弱化版(我为什么做题总喜欢先挑难的做QAQ)

$k$对点对$(i,j)$有贡献,当且仅当$a_k=max(a_{i+1},a_{i+2},...,a_{r-1})$,且$a_k<a_i\&\&a_k<a_j$。

那么我们可以使用单调栈求出i左面第一个比它大的位置$lp[i]$,和右面第一个比它大的位置$rp[i]$,那么点对$(lp[i],rp[i])$就是满足第二个条件的点对。

但是这样还不行,因为在本题中可能会出现相同的数,它们的贡献可能是一样的,但是一个点对却只能被计算一次。

所以我们固定在贡献相同的点中让最左边的点产生贡献,其余不产生贡献。所以再使用单调栈求出i左面第一个大于等于它的位置$lf[i]$,那么只把$lp[i]=lf[i]$的点的贡献考虑进答案中。

然后问题就转化为:给定平面上一些点(不超过n个),求以$(a,a)$和$(b,b)$为顶点的矩形中有多少个节点(包括边界)

对于每个横坐标建立一棵可持久化线段树,对于一个点在它横坐标版本的可持久化线段树中插入它纵坐标位置的数。

最后查询时就是查对于区间[a,b],root[b]与root[a-1]的差。

最后再把第一种情况的答案(当然是要单独拿出来处理啊!)加上并输出即可。

#include <cstdio>
#include <algorithm>
#define N 300010
using namespace std;
struct data
{
int x , y;
bool operator<(const data a)const {return x < a.x;}
}a[N];
int v[N] , lp[N] , rp[N] , lf[N] , sta[N] , top , cnt , root[N] , ls[N * 20] , rs[N * 20] , si[N * 20] , tot;
void insert(int p , int l , int r , int x , int &y)
{
y = ++tot , si[y] = si[x] + 1;
if(l == r) return;
int mid = (l + r) >> 1;
if(p <= mid) rs[y] = rs[x] , insert(p , l , mid , ls[x] , ls[y]);
else ls[y] = ls[x] , insert(p , mid + 1 , r , rs[x] , rs[y]);
}
int query(int b , int e , int l , int r , int x , int y)
{
if(b <= l && r <= e) return si[y] - si[x];
int mid = (l + r) >> 1 , ans = 0;
if(b <= mid) ans += query(b , e , l , mid , ls[x] , ls[y]);
if(e > mid) ans += query(b , e , mid + 1 , r , rs[x] , rs[y]);
return ans;
}
int main()
{
int n , m , type , i , j , x , y , last = 0;
scanf("%d%d%d" , &n , &m , &type);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &v[i]);
v[0] = v[n + 1] = 1 << 30;
for(i = 1 ; i <= n ; i ++ )
{
while(v[sta[top]] <= v[i]) top -- ;
lp[i] = sta[top] , sta[++top] = i;
}
top = 0 , sta[0] = n + 1;
for(i = n ; i >= 1 ; i -- )
{
while(v[sta[top]] <= v[i]) top -- ;
rp[i] = sta[top] , sta[++top] = i;
}
top = 0 , sta[0] = 0;
for(i = 1 ; i <= n ; i ++ )
{
while(v[sta[top]] < v[i]) top -- ;
lf[i] = sta[top] , sta[++top] = i;
}
for(i = 1 ; i <= n ; i ++ )
if(lp[i] && rp[i] <= n && lp[i] == lf[i])
a[++cnt].x = lp[i] , a[cnt].y = rp[i];
sort(a + 1 , a + cnt + 1);
for(i = j = 1 ; i <= n ; i ++ )
{
root[i] = root[i - 1];
while(j <= cnt && a[j].x == i) insert(a[j].y , 1 , n , root[i] , root[i]) , j ++ ;
}
while(m -- )
{
scanf("%d%d" , &x , &y);
if(type == 1) x = (x + last - 1) % n + 1 , y = (y + last - 1) % n + 1;
if(x > y) swap(x , y);
printf("%d\n" , last = query(x , y , 1 , n , root[x - 1] , root[y]) + y - x);
}
return 0;
}

【bzoj3956】Count 单调栈+可持久化线段树的更多相关文章

  1. 【bzoj4826】[Hnoi2017]影魔 单调栈+可持久化线段树

    题目描述 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵魂,都有着自己 ...

  2. BZOJ 4826: [Hnoi2017]影魔 单调栈+可持久化线段树

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个 ...

  3. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  4. bzoj3956: Count (单调栈+st表)

    题面链接 bzoj 题解 非常巧妙的一道题 类似[hnoi影魔] 每个点会给左右第一个大于它的点对产生贡献 可以用单调栈求出 这里有点小细节,就是处理相等的点时,最左边的点管左边的贡献,最右边的点管最 ...

  5. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  6. BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)

    题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...

  7. [BZOJ4826][HNOI2017]影魔 可持久化线段树

    链接 题意:给你 \(1\) 到 \(n\) 的排列 \(k_1,k_2,\dots,k_n\) ,对 \(i,j (i<j)\)来说,若不存在 \(k_s (i<s<j)\) 大于 ...

  8. 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)

    有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...

  9. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

随机推荐

  1. (转载)最近总是遇到各种 IEbug,mark一下,学习到了,转载出处:http://www.cnblogs.com/ruomeng/p/5332814.html

    本文分享下我在项目中积累的IE8+兼容性问题的解决方法.根据我的实践经验,如果你在写HTML/CSS时候是按照W3C推荐的方式写的,然后下面的几点都关注过,那么基本上很大一部分IE8+兼容性问题都OK ...

  2. 新萝卜家园GHOST WIN7系统3专业装机版

    系统来自系统妈:http://www.xitongma.com/ 系统概述 萝卜家园GHOST win7 64位装机旗舰版加快“网上邻居”共享速度:取消不需要的网络服务组件,系统支持Windows安装 ...

  3. PHP开发基础视频教程

    PHP现今作为互联网运用很广泛的编程语言,市场需求量也越来越高,而PHP开发工程师的薪资也是一路水涨船高,更多的人看到了PHP的发展前景,纷纷都想投入到PHP的开发大军中来,那么对于很多转行或者零基础 ...

  4. 一个具体的例子学习Java volatile关键字

    相信大多数Java程序员都学习过volatile这个关键字的用法.百度百科上对volatile的定义: volatile是一个类型修饰符(type specifier),被设计用来修饰被不同线程访问和 ...

  5. java 核心技术卷一笔记 6 .2.3 接口 lambda 表达式 内部类

    6.2.3   对象克隆 Cloneable 接口,这个接口指示一个类提供了一个安全的clone方法.(稍作了解) 为一个对象引用的变量建立副本时,原变量和副本都是同一个对象的引用,任何一个变量改变都 ...

  6. mongo ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused

    解决方法 rm /var/lib/mongodb/mongod.lock

  7. UVALive 4287 Proving Equivalence (强连通分量)

    把证明的关系看出一张图,最终就是要所有的点都在至少一个环中.环的判断和度数有关. 用tarjan找强连通分量,在一个强连通分量点已经等价缩点以后形成一个DAG,计算入度为0的点数a, 出度为0的b,取 ...

  8. [NOI2010]海拔——最小割+对偶图

    题目链接 SOLUTION 想一下最优情况下肯定让平路或下坡尽量多,于是不难想到这样构图:包括左上角的一部分全部为\(0\),包括右下角的一部分全部为\(1\),于是现在问题转化为求那个分界线是什么. ...

  9. HTML5触摸事件

    touchstart .touchmove .touchend 事件 touchstart事件:当手指触摸屏幕时触发,即使有一个手指放在屏幕上也会触发. touchmove事件:当手指在屏幕上滑动时触 ...

  10. Python运算符总结

    一.简介 Python中运算符分为: 算术运算符:主要用于两个对象算数计算(加减乘除等运算) 比较(关系)运算符:用于两个对象比较(判断是否相等.大于等运算) 赋值运算符:用于对象的赋值,将运算符右边 ...