【BZOJ3956】Count,单调栈+ST表维护区间最大值
来源:互联网 发布:xnview mp mac 编辑:程序博客网 时间:2024/05/17 01:24
Time:2016.08.11
Author:xiaoyimi
转载注明出处谢谢
传送门
思路: TA爷眼中的水题
首先有个特别的结论
总共的点对数不会超过2n
因为对于元素i来说,如果只考虑与比它高的元素进行配对
那么最多左边一个,右边一个,再靠左或靠右的就不满足配对条件了
考试的时候我想到的是单调栈维护一个不上升的序列,但不知道具体并不会做
讲题时使用了ST表维护区间最大
(为什么不用线段树?因为线段树常数比较大……而且这里是静态查询,正好是RMQ经典操作)
考虑区间[l,r]
找出[l,r]中最大高度的下标k
显然l~k-1不能和k之后的元素配对
k+1~r不能和k之前的元素配对
ans=[l,k]在[l,k]中的配对个数+[k,r]在[k,r]中的配对个数
这个是可以前缀和维护的
前后各扫一遍
f[i]指i在[1,i]中配对数量
g[i]指i在[i,n]中配对数量
sum1[i]=Σf[j] 1<=j<=i
sum2[i]=Σg[j] i<=j<=n
ans=sum1[r]-sum1[k]+sum[l]-sum2[k]
注意高度相等时的处理,这里很恶心,我就不细说了ORZ
#include<cstdio>#include<iostream>#include<cmath> #define M 300003#define pd(x,y) (a[x]>a[y]?x:y)using namespace std;int in(){ int t=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-48,ch=getchar(); return t;}int n=in(),m=in(),tp=in();int sum1[M],sum2[M],S[M];int a[M],fa[M][19];int RMQ(int x,int y){ int t=log2(y-x+1); return pd(fa[x][t],fa[y-(1<<t)+1][t]);}main(){ for (int i=1;i<=n;i++) a[i]=in(); for (int i=1;i<=n;i++) { for (;S[0];S[0]--) { sum1[i]++; if (a[S[S[0]]]>=a[i]) break; } for (;S[0];S[0]--) if (a[S[S[0]]]>a[i]) break; S[++S[0]]=i; sum1[i]+=sum1[i-1]; } S[0]=0; for (int i=n;i>=1;i--) { for (;S[0];S[0]--) { sum2[i]++; if (a[S[S[0]]]>=a[i]) break; } for (;S[0];S[0]--) if (a[S[S[0]]]>a[i]) break; S[++S[0]]=i; sum2[i]+=sum2[i+1]; } for (int i=1;i<=n;i++) fa[i][0]=i; for (int i=1;(1<<i)<=n;i++) for (int j=1;j+(1<<i)-1<=n;j++) fa[j][i]=pd(fa[j][i-1],fa[j+(1<<i-1)][i-1]); int mx,l,r,L,R,lastans=0; for (;m;m--) { l=in();r=in(); if (tp) L=min((lastans+l-1)%n,(lastans+r-1)%n)+1, R=max((l+lastans-1)%n,(r+lastans-1)%n)+1; else L=l,R=r; mx=RMQ(L,R); printf("%d\n",lastans=sum1[R]-sum1[mx]-sum2[mx]+sum2[L]); }}
其实也可以写主席树的,但我被相等情况的处理恶心到了,所以没有写下去……
0 0
- 【BZOJ3956】Count,单调栈+ST表维护区间最大值
- ST表模板(维护区间最大值)
- 【bzoj3956】【Count】【主席树+单调栈】
- [BZOJ3956]Count(单调栈+线段树)
- [BZOJ3956]Count(单调栈+线段树)
- 【BZOJ】3956 Count 单调栈+ST表
- st表求区间最大值
- CodeForces601D【单调栈维护最大值】
- bzoj 3956: Count (单调栈+st表)
- bzoj3956 -- 单调栈 + 线段树
- BZOJ3956 Count
- [bzoj3956] Count
- bzoj3956:Count
- RMQ之ST表维护区间极值
- 【技巧】线段树维护区间单调栈
- ST 求区间最大值板子
- codeforces 713D 二维ST表维护最大值
- 玲珑杯oj1149区间最大值最小值--st表
- HDU 1043 Eight(BFS)
- log4j配置信息
- Java7并发编程--3、线程同步辅助类
- PropertiesConfiguration读取属性文件
- wordpress 修改固定连接提示页面404错误
- 【BZOJ3956】Count,单调栈+ST表维护区间最大值
- Jsp页面迭代、取值、选择标签
- 淘淘商城---8.11
- 【面试】GDB调试
- java设计模式-装饰者模式
- hdu5816Hearthstone(状压DP)
- 05全栈工程师--2016-08-10
- Foundation框架中的NSString 不可变字符串
- Cookie利用神器:CookieHacker