ACdream 1108 分块
来源:互联网 发布:macbookpro必装软件 编辑:程序博客网 时间:2024/04/30 10:24
题意:给定一个数列,然后有一堆的询问,问在闭区间[l,r]中出现了至少k次的多少个数
解法:对区间的数的出现次数分块 一共分成sqrt(n)块 对于所有在同一个块中的元素而言,它的左边最多滑动sqrt(n),右边最多滑动n 那么就是n*sqrt(n);
对于不同块的而言 最多出现sqrt(n)对 也就是边界 而每一对的左边最多滑动n右边最多滑动n 也是n*sqrt(n)
也就是总体复杂度都在n*sqrt(n)
但是对于这个问题还有需要对频率进行查询 那么我们采用二分 也还是 n*sqrt(n)
#include<cstdio>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<cmath>using namespace std;#define maxn 111111#define sqr (350)#define mid ((l+r)>>1)int cnt[maxn],fre[maxn],a[maxn],ll[maxn],rr[maxn],kk[maxn],id[maxn];int ans[maxn];int n,m;int cmp(int x,int y){ if(ll[x]/sqr==ll[y]/sqr){ return rr[x]<rr[y]; }else return ll[x]<ll[y];}int bin(int fr){ int l=1,r=100001; int ans=1; while(l<=r){ if(fre[mid]>=fr){ans=mid;l=mid+1;} else r=mid-1; }return ans;}int main(){ int _;scanf("%d",&_); while(_--){ scanf("%d%d",&n,&m); for(int i=0;i<n;++i)scanf("%d",&a[i]); for(int i=0;i<m;++i){ scanf("%d%d%d",&ll[i],&rr[i],&kk[i]);--ll[i],--rr[i]; id[i]=i; } sort(id,id+m,cmp); memset(cnt,0,sizeof cnt); memset(fre,0,sizeof fre); int nowl=0,nowr=-1; for(int i=0;i<m;++i){ int l=ll[id[i]],r=rr[id[i]],k=kk[id[i]]; while(nowr<r)fre[++cnt[a[++nowr]]]++; while(nowl>l)fre[++cnt[a[--nowl]]]++; while(nowl<l)fre[cnt[a[nowl++]]--]--; while(nowr>r)fre[cnt[a[nowr--]]--]--; ans[id[i]]=bin(k); } for(int i=0;i<m;++i)printf("%d\n",ans[i]); } return 0;}
0 0
- ACdream 1108 分块
- ACdream 1738 世风日下的哗啦啦族I(分块)
- ACdream 1738 世风日下的哗啦啦族I(分块)
- acdream 1738 世风日下的哗啦啦族I (分块)
- ACdream
- Acdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- acdreamOJ 1108分块算法
- 2014年暑假总结
- 函数调用过程探究
- GreenDao 学习笔记 1
- uva 10651 Pebble Solitaire(动态规划:记忆化搜索)
- Java编程思想(七) —— 内部类
- ACdream 1108 分块
- android编程异常解决 FATAL EXCEPTION: main android.view.InflateException: Binary XML file line #195: Erro
- 用模板写选择排序-链表
- 求二叉树中节点的最大距离
- UVA - 10601 Cubes (组合+置换)
- String to Integer (atoi)
- ZOJ Problem Set - 2750
- Android开源项目QuickReturnHeader分析
- Reverse Words in a String