Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 45757 | Accepted: 15221 | |
Case Time Limit: 2000MS |
Description
Input
Output
Sample Input
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
Sample Output
5
6
3
Hint
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct node { int val,id; }a[100010]; int cmp(node x, node y) { return x.val < y.val; } int main() { int n,m,i,j,l,r,k; while(scanf("%d%d",&n,&m)!=EOF) { for(i = 0; i < n; ++i) { scanf("%d",&a[i].val); a[i].id = i; } sort(a, a+n, cmp); while(m--) { scanf("%d%d%d",&l, &r, &k); l--; r--; for(j=0; j<n; ++j) { if(a[j].id>=l&&a[j].id<=r) k--; if(!k) { printf("%d\n",a[j].val); break; } } } } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define maxn 100010 #define B 1000//桶的大小 int n,m; int a[maxn],num[maxn];//num[]表示对a排序之后的结果 vector<int> bucket[maxn/B]; int main() { int i,j,l,r,k; while(scanf("%d%d",&n, &m)!=EOF) { for(i = 0; i < n; ++i) { scanf("%d",&a[i]); bucket[i / B].push_back(a[i]);//分桶 num[i] = a[i]; } sort(num, num + n); for(i = 0; i < n / B; ++i) sort(bucket[i].begin(), bucket[i].end() );//对每个桶进行排序 while(m--) { scanf("%d%d%d",&l, &r, &k); int left = -1, right = n-1, mid;//求[left,right)区间中的第k个书 while(right - left > 1) { mid = (left + right) / 2; int x = num[mid]; int tl = l-1, tr = r, c = 0; //区间两端多出的部分 while(tl < tr && tl % B != 0) { if(a[tl++] <= x) c++; } while(tl < tr && tr % B != 0) { if(a[--tr] <= x) c++; } while(tl < tr)//对每一个桶进行计算 { i = tl / B; c += upper_bound(bucket[i].begin(), bucket[i].end(), x) - bucket[i].begin(); tl += B; } if(c >= k) right = mid; else left = mid; } printf("%d\n",num[right]); } return 0; } }
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define maxn 100010 #define lson l,mid,i<<1 #define rson mid+1,r,i<<1|1 vector<int>T[maxn<<2]; void build(int l,int r,int i)//建立线段树,i是节点编号,与区间[l,r)相对应 { if(l==r) { int val; scanf("%d",&val); T[i].clear(); T[i].push_back(val); return ; } int mid=(l+r)>>1; build(lson); build(rson); T[i].resize(r-l+1);//调整容器T[i]的大小为 r-l+1 merge(T[i<<1].begin(),T[i<<1].end(),T[i<<1|1].begin(),T[i<<1|1].end(),T[i].begin() ); //将两个儿子的数列合并 } //计算区间[ql,qr)中不超过val的个数 int query(int ql,int qr,int val,int l,int r,int i) { if(ql==l&&qr==r) return upper_bound(T[i].begin(),T[i].end(),val)-T[i].begin(); int mid=(l+r)>>1; if(qr<=mid) return query(ql,qr,val,lson); else if(ql>mid) return query(ql,qr,val,rson); return query(ql,mid,val,lson)+query(mid+1,qr,val,rson); } int main() { int n,m,a,b,k,c,left,right,mid; while(scanf("%d%d",&n,&m)!=EOF) { build(1,n,1); while(m--) { scanf("%d%d%d",&a,&b,&k); left=-1; right=n-1; while(right-left>1)//二分查找 { mid=(left+right)>>1; c=query(a,b,T[1][mid],1,n,1); if(c>=k) right=mid; else left=mid; } printf("%d\n",T[1][right]); } } return 0; }