POJ 2104&&2761 不修改的K大数 (主席树)
题目:查询区间的K小数,不修改继续跟着岛娘,适妞学习主席树~~~~离散化。以每个位置为起点,建立一棵主席树,保存后缀区间的情况。由于每个位置的主席树其实是构造是完全相同的在查询的时候,便可以直接相减,T[l]-T[r+1]便是[l,r]区间的情况。依旧是从后往前更新,建立主席树。。在前一个位置的基础上,新建一棵树,在当前位置更新[cpp]int n,q,m,tot;int a[N],t[N];int T[M],lson[M],rson[M],c[M];void Init_hash(){for(int i=1;i<=n;i++)t[i]=a[i];sort(t+1,t+1+n);m=unique(t+1,t+1+n)-t-1;}int bulid(int l,int r){int root=tot++;c[root]=0;if(l!=r){int mid=(l+r)>>1;lson[root]=bulid(l,mid);rson[root]=bulid(mid+1,r);}return root;}int hash(int x){return lower_bound(t+1,t+1+m,x)-t;}int update(int root,int pos,int val){int newroot=tot++,tmp=newroot;c[newroot]=c[root]+val;int l=1,r=m;while(l<r){int mid=(l+r)>>1;//cout<<l<<" "<<r<<endl;if(pos<=mid){lson[newroot]=tot++;rson[newroot]=rson[root];newroot=lson[newroot];root=lson[root];r=mid;}else{rson[newroot]=tot++;lson[newroot]=lson[root];newroot=rson[newroot];root=rson[root];l=mid+1;}c[newroot]=c[root]+val;}return tmp;}int query(int left_root,int right_root,int k){int l=1,r=m;while(l<r){int mid=(l+r)>>1;if(c[lson[left_root]]-c[lson[right_root]]>=k){r=mid;left_root=lson[left_root];right_root=lson[right_root];}else{l=mid+1;k-=c[lson[left_root]]-c[lson[right_root]];left_root=rson[left_root];right_root=rson[right_root];}}return l;}int main(){while(scanf("%d%d",&n,&q)!=EOF){tot=0;for(int i=1;i<=n;i++)scanf("%d",&a[i]);Init_hash();T[n+1]=bulid(1,m);for(int i=n;i;i--){int pos=hash(a[i]);T[i]=update(T[i+1],pos,1);}while(q--){int l,r,k;scanf("%d%d%d",&l,&r,&k);printf("%d\n",t[query(T[l],T[r+1],k)]);}}return 0;}int n,q,m,tot;int a[N],t[N];int T[M],lson[M],rson[M],c[M];void Init_hash(){for(int i=1;i<=n;i++)t[i]=a[i];sort(t+1,t+1+n);m=unique(t+1,t+1+n)-t-1;}int bulid(int l,int r){int root=tot++;c[root]=0;if(l!=r){int mid=(l+r)>>1;lson[root]=bulid(l,mid);rson[root]=bulid(mid+1,r);}return root;}int hash(int x){return lower_bound(t+1,t+1+m,x)-t;}int update(int root,int pos,int val){int newroot=tot++,tmp=newroot;c[newroot]=c[root]+val;int l=1,r=m;while(l<r){int mid=(l+r)>>1;//cout<<l<<" "<<r<<endl;if(pos<=mid){lson[newroot]=tot++;rson[newroot]=rson[root];newroot=lson[newroot];root=lson[root];r=mid;}else{rson[newroot]=tot++;lson[newroot]=lson[root];newroot=rson[newroot];root=rson[root];l=mid+1;}c[newroot]=c[root]+val;}return tmp;}int query(int left_root,int right_root,int k){int l=1,r=m;while(l<r){int mid=(l+r)>>1;if(c[lson[left_root]]-c[lson[right_root]]>=k){r=mid;left_root=lson[left_root];right_root=lson[right_root];}else{l=mid+1;k-=c[lson[left_root]]-c[lson[rig补充:软件开发 , C++ ,
上一个:九度教程第34题
下一个:特殊的pandigital数(有人译数独数)
- 更多C/C++疑问解答:
- 关于c++的cout输出的问题。
- 在学校里学过C和C++,不过学的很一般,现在自学C#,会不会很难?
- 全国计算机二级C语言笔试题
- 已知某树有2个2度结点,3个3度结点,4个4度结点,问有几个叶子结点?
- c++数据结构内部排序问题,整数排序
- 2012九月计算机二级C语言全国题库,,急求急求
- 如果assert只有一个字符串作为参数,是什么意思呢?
- C语言中,哪些运算符具有左结合性,哪些具有右结合性,帮忙总结下,谢谢了!
- 为什么用结构体编写的程序输入是,0输不出来啊~~~
- 将IEEE—754的十六进制转化为十进制浮点类型,用C或C++都行,多谢各位大侠啊,非常感谢!
- 为什么这个程序求不出公式?
- 这个链表倒置的算法请大家分析下
- c语言函数库调用
- C语言unsigned int纠错
- C语言快排求解啊