bzoj3956:Count
来源:互联网 发布:java高并发架构 编辑:程序博客网 时间:2024/06/05 20:37
ST表+单调栈
先用单调栈O(n)处理出以每个点为左、右端点的所有的点对组数。
然后考虑询问区间,用ST表找出区间内最大点的位置,所有好的点对都不会跨越这个点
然后以最大点左边所有点为左端点的好的点对+以最大点右边所有点为右端点的好的点对便是最后的答案(前缀和处理)
今天算是复习 学习了ST表和单调栈
挺好的一道题
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>using namespace std;int n,m,type;int a[300005];int sta[300005];int lc[300005],rc[300005];int lcs[300005],rcs[300005];int kp[300005][21];int pw[21],we[300005];int tail=0,ma=0;int last=0,ans=0;void lcr(){ int i,j,k,l; for(i=1;i<=n;i++){ if(tail==0){tail++;sta[tail]=i;continue;} while(a[sta[tail]]<a[i]&&tail!=0){lc[sta[tail]]++;rc[i]++;tail--;} if(a[sta[tail]]==a[i]&&tail!=0){lc[sta[tail]]++;rc[i]++;sta[tail]=i;continue;} tail++; if(tail!=1){ lc[sta[tail-1]]++; rc[i]++; } sta[tail]=i; } for(i=1;i<=n;i++){ lcs[i]=lcs[i-1]+lc[i]; rcs[i]=rcs[i-1]+rc[i]; }}inline int lose(int x,int y){ if(a[x]<a[y])return y; return x;}void ST(){ int i,j,k=n,l,tot=0; pw[0]=1;we[0]=0; for(i=1;i<=n;i++){ if(i==pw[tot]){tot++;pw[tot]=pw[tot-1]*2;we[i]=we[i-1]+1;continue;} we[i]=we[i-1]; } for(i=1;i<=n;i++)kp[i][0]=i; for(i=1;i<=we[n];i++) for(j=1;j+pw[i]-1<=n;j++) kp[j][i]=lose(kp[j][i-1],kp[j+pw[i-1]][i-1]);}int main(){ int i,j,k,l,x,y,t; scanf("%d%d%d",&n,&m,&type); for(i=1;i<=n;i++)scanf("%d",&a[i]); lcr(); ST(); if(type==0){ for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); l=we[y-x+1]-1; ma=lose(kp[x][l],kp[y-pw[l]+1][l]); ans=lcs[ma-1]-lcs[x-1]+rcs[y]-rcs[ma]; printf("%d\n",ans); } } else{ for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); x=(x+last-1)%n+1; y=(y+last-1)%n+1; t=min(x,y); y=max(x,y); x=t; l=we[y-x+1]-1; ma=lose(kp[x][l],kp[y-pw[l]+1][l]); ans=lcs[ma-1]-lcs[x-1]+rcs[y]-rcs[ma]; last=ans; printf("%d\n",ans); } } return 0;}
0 0
- BZOJ3956 Count
- [bzoj3956] Count
- bzoj3956:Count
- [bzoj3956]Count 解题报告
- bzoj3956 Count 解题报告
- 【bzoj3956】【Count】【主席树+单调栈】
- [BZOJ3956]Count(单调栈+线段树)
- [BZOJ3956]Count(单调栈+线段树)
- 【BZOJ3956】Count,单调栈+ST表维护区间最大值
- bzoj3956 -- 单调栈 + 线段树
- Count
- COUNT
- count
- Count
- count
- count
- count
- count
- Mybatis逆向工程
- 机器学习实战之K-近邻算法总结和代码解析
- vim如何添加或删除多行注释
- 字节流与字符流区别详解
- BZOJ2705 [SDOI2012]Longge的问题 【欧拉函数】
- bzoj3956:Count
- Servlet
- linux1
- vue2.0父子组件间通信
- va_start和va_end使用详解
- populating-next-right-pointers-in-each-node
- vim编辑器中如何查找某个词
- vue.js 实现 todo list 任务表单-2
- hdu1162 Eddy's picture 最小生成树 prim