题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6621
题意:给你一个数组,然后有m次询问,每次询问都有一个区间和一个p值,然后让你求离排
#include<iostream> #include<cmath> #include<stdio.h> #include<algorithm> #include<cstring> #include<map> #include<vector> using namespace std; int n, m; int a[1000005]; vector<int>v[2000005]; vector<int>::iterator it; void build(int id,int l,int r) { v[id].clear(); for (int i=l; i<=r; i++) v[id].push_back(a[i]); sort(v[id].begin(),v[id].end()); if (l==r) return; int mid=(l+r)/2; build(2*id,l,mid); build(2*id+1,mid+1,r); } int query(int id,int L,int R,int l,int r,int h) { if(l<=L&&R<=r) { it=upper_bound(v[id].begin(),v[id].end(),h); return it-v[id].begin(); } int mid=(L+R)/2; int ans=0; if(l<=mid) ans+=query(id<<1,L,mid,l,r,h); if (mid<r) ans+=query(id<<1|1,mid+1,R,l,r,h); return ans; } int main() { int T; while(~scanf("%d",&T)) { while(T--) { int mxv; scanf("%d%d",&n,&m); for (int i=1; i<=n; i++) scanf("%d",&a[i]); build(1,1,n); int ans=0; mxv=*max_element(a+1,a+1+n); while(m--) { int l,r,p,k; scanf("%d%d%d%d",&l,&r,&p,&k); l^=ans,r^=ans,p^=ans,k^=ans; int begin=0,end=mxv; while(end>=begin) { int hf=(begin+end)/2; int t=query(1,1,n,l,r,p+hf)-query(1,1,n,l,r,p-hf-1); if (t<k) { begin=hf+1; } else { end=hf-1; } } printf("%d ",ans=begin); } } } return 0; }
第k近的数是多少
思路:第k近肯定会想到主席树,不过这个题要二分才行,不然会超时的。