ssoj2427: 学数数(RMQ)
2015-10-04 13:35
260 查看
题意:一个数组有n个数,能够分成n(n+1)/2个连续子数组。记录这些子数组的最大数。有q个询问,求满足询问的数字有多少个。
思路:o^2肯定超。离散化。对于当前的数,找到他左右两边第一个大于它的数,左边的距离(x),右边的距离(y),f[当前数]+=x+y+x*y。RMQ记录区间最大值。
各种细节写挂了。。。(1)要开long long,与ll相关的也要ll。(2)因为离散了,所以对询问的数要判断一下是否是离散前的数。。。
贴代码:
思路:o^2肯定超。离散化。对于当前的数,找到他左右两边第一个大于它的数,左边的距离(x),右边的距离(y),f[当前数]+=x+y+x*y。RMQ记录区间最大值。
各种细节写挂了。。。(1)要开long long,与ll相关的也要ll。(2)因为离散了,所以对询问的数要判断一下是否是离散前的数。。。
贴代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <algorithm> #define ll long long using namespace std; const int maxn=1000006; int n,q,k,a[maxn],b[maxn],dp[100005][31],p[100005][31],mxb=0,mx=0; ll f[maxn],ans,cnt=0,sum[maxn]; inline int get(){ char c;while(!isdigit(c=getchar())); int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48; return v; } inline void RMQ(){ for(int i=1;i<=n;++i)dp[i][0]=a[i],p[i][0]=i; int k=log2(n*1.0); for(int j=1;j<=k;++j) for(int i=1;i+(1<<j)-1<=n;++i){ if(dp[i+(1<<(j-1))][j-1]>dp[i][j-1])dp[i][j]=dp[i+(1<<(j-1))][j-1],p[i][j]=p[i+(1<<(j-1))][j-1]; else dp[i][j]=dp[i][j-1],p[i][j]=p[i][j-1]; } } inline int getpos(int l,int r){ int k=log2((r-l+1)*1.0); if(dp[l][k]>dp[r-(1<<k)+1][k])return p[l][k]; else return p[r-(1<<k)+1][k]; } inline void Find(int l,int r){ if(l>=r)return; int t=getpos(l,r); int x=t-l,y=r-t; f[a[t]]+=(ll)x+(ll)y+(ll)x*y; Find(l,t-1); Find(t+1,r); } int main(){ n=get();q=get(); for(int i=1;i<=n;++i)b[i]=a[i]=get(),mxb=max(mxb,b[i]); sort(b+1,b+1+n); int tmp=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+tmp,a[i])-b,++f[a[i]],mx=max(a[i],mx); RMQ(); Find(1,n);sum[0]=f[0]=0; for(int i=1;i<=mx;++i)sum[i]+=sum[i-1]+f[i-1],cnt+=f[i]; while(q--){ char op; op=getchar(); while(!(op=='>'||op=='='||op=='<'))op=getchar(); int x=get(); int t=lower_bound(b+1,b+1+tmp,x)-b; if(op=='>'){ if(t>mx)ans=0; else{ if(x!=b[t])ans=cnt-sum[t]; else ans=cnt-sum[t]-f[t]; } } if(op=='='){ if(x==b[t])ans=f[t]; else ans=0; } if(op=='<'){ if(t>mx)ans=cnt; else ans=sum[t]; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 如何将PreparedStatement查询得到的结果集存储起来--方法二:采用列表List
- 软件工程文档总结
- iOS_NSAttributeString
- dede 常用网站开发标签
- BIOS入门之我见-预热
- Redis数据类型,以及应用场合
- redis 部署
- dede 搜索功能
- 一道百度的盒子模型的笔试题
- 有些事关于敏捷
- Rem & Viewport
- 证券基础--信息披露
- win8和win10下,visual studio 2008 调试出现无响应的卡死问题解决
- RPC协议、http协议、tcp/ip协议、udp协议、socket协议以及soap协议都有什么相同点和不同点
- CCS3.3的使用2___统计程序运行的时间
- 如何将PreparedStatement查询得到的结果集存储起来--方法一:采用对象数组
- (ZT) CHS conversion
- 把sshkey添加到git agent上
- 3.算法-二叉树遍历
- java17:修饰词