HDU 2665 Kth number(可持续化线段树)
来源:互联网 发布:2017微信数据报告 编辑:程序博客网 时间:2024/05/29 03:20
Kth number
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9213 Accepted Submission(s): 2868
Problem Description
Give you a sequence and ask you the kth big number of a inteval.
Input
The first line is the number of the test cases.
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
Output
For each test case, output m lines. Each line contains the kth big number.
Sample Input
1 10 1 1 4 2 3 5 6 7 8 9 0 1 3 2
Sample Output
2这道题目网上的题解大多是划分树解法,其实求区间第K大还有一个方法就是可持久化线段树,这里由于给的值可能是负数,必须离散化,而且离散化之后的线段树空间可以开的更小一点防止内存超限#include <iostream>#include <string.h>#include <stdlib.h>#include <algorithm>#include <math.h>#include <stdio.h>#include <map>using namespace std;const int maxn=1e5;int rt[maxn+5];int ls[maxn*18+5];int rs[maxn*18+5];int sum[maxn*18+5];int b[maxn+5];int a[maxn+5];int n,m;int l,r;int p;map<int,int> m1,m2;void update(int &node,int l,int r,int val){ if(!node) { sum[p]=ls[p]=rs[p]=0; node=p; p++; } else { sum[p]=sum[node];ls[p]=ls[node]; rs[p]=rs[node];node=p; p++; } if(l==r) { sum[node]++; return; } sum[node]++; int mid=(l+r)>>1; if(val<=mid) update(ls[node],l,mid,val); else update(rs[node],mid+1,r,val);}int query(int node1,int node2,int l,int r,int k){ if(sum[node2]-sum[node1]<k) return -1; if(l==r) return l; int mid=(l+r)>>1; int num=sum[ls[node2]]-sum[ls[node1]]; if(num>=k) return query(ls[node1],ls[node2],l,mid,k); else return query(rs[node1],rs[node2],mid+1,r,k-num);}int main(){ int t; scanf("%d",&t); int s,e,k; while(t--) { l=1e9;r=0; m1.clear(); m2.clear(); scanf("%d%d",&n,&m); p=1; for(int i=1;i<=n;i++) { scanf("%d",&b[i]); a[i]=b[i]; } sort(b+1,b+n+1); for(int i=1;i<=n;i++) { m1[b[i]]=i; m2[i]=b[i]; } l=1,r=n; update(rt[1]=0,l,r,m1[a[1]]); for(int i=2;i<=n;i++) update(rt[i]=rt[i-1],l,r,m1[a[i]]); int ans; for(int i=1;i<=m;i++) { scanf("%d%d%d",&s,&e,&k); ans=query(rt[s-1],rt[e],l,r,k); printf("%d\n",m2[ans]); } } return 0;}
0 0
- HDU 2665 Kth number(可持续化线段树)
- HDU_2665 Kth number[可持续化线段树]
- hdu 2665 Kth number ( 可持久化线段树 )
- hdu 2665 Kth number(函数化线段树)
- HDU 2665 Kth number 可持久化线段树
- HDU-2665 Kth number (可持久化线段树)
- HDU 2665 Kth number 可持久化线段树
- hdu 4348 可持续化线段树
- hdu 2665 Kth number(线段树+归并树+二分)
- HDU 2665 Kth number 主席树,函数式线段树
- HDU 2665 Kth number [可持久化线段树 主席树]
- hdu 2665 Kth number 可持(逗)久(比)化线段树
- 可持续化线段树
- hdu 2665 Kth number
- Hdu 2665 Kth number
- HDU 2665 Kth number
- HDU 2665 Kth number
- hdu 2665 Kth number
- jdk&jmeter环境变量配置
- 【C语言】再次找的一些C语言题目,关于折半查找和某些种种
- 【C语言】一些关于二进制位的一些题题目哦。
- 【C语言】关于atoi,itoa与itob的重写和字符统计
- 【C语言】3子棋游戏,
- HDU 2665 Kth number(可持续化线段树)
- 【C语言】一些面试题。
- 【C语言】在字符串中找出第一个只出现一次的字符。 如输入“abaccdeff”,则输出'b'。
- 【C语言】杨氏矩阵C语言实现
- 【C语言】学生成绩链表的录入
- 【C语言】在终端输入多行信息,找出包含“ould”的行,并打印改行。
- 【C语言】冒泡排序与回文判断
- 【C语言】把从1到1000的数打印出来,但你不能使用任何的循环语句或是条件语句。
- 【C语言】strlen的三种实现方法,strcmp,strcat,strcpy