标签:理解 题目 air distance mod main turn show 完全
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6621
题意:T(3)组样例,n(1e5)个数,q(1e5)次查询,查询[l , r] 内, | a[i] - p | 第k大的数,且强制要求离线化
分析:初始的思路是跟着修改,想着用动态主席树来做,但是并不会,而且也很慢,事实上完全可以通过静态主席树来做
主席树的结点直接就是1e6个值,不需要进行离散化,我们是对每个值都单独统计出现的次数的
用二分,查询(p-mid,p+mid)中数的个数,具体实现看代码,复杂度为O(q*log(m)*log(m)),查询代码改的有点像线段树区间求和了,可以帮助理解
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> P; const int mod=1e9+7; const int maxn=1e5+7; const int maxm=1e4+7; const int inf=1<<30; const int M=1e6; const double pi=acos(-1); int nodeNum; int L[maxn<<6],R[maxn<<6],sum[maxn<<6]; int a[maxn]; int T[maxn]; int read() { int ans=0,flag=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) flag=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) {ans=(ans<<3)+(ans<<1)+ch-‘0‘;ch=getchar();} return ans*flag; } int update(int pre,int l,int r,int x) //pre为旧树该位置节点的编号 { int num=++nodeNum; L[num]=L[pre];R[num]=R[pre];sum[num]=sum[pre]+1; if(l!=r) { int m=(l+r)>>1; if(x<=m) L[num]=update(L[pre],l,m,x); else R[num]=update(R[pre],m+1,r,x); } return num; } int query(int u,int v,int l,int r,int pl,int pr) { if(l>=pl&&r<=pr) return sum[v]-sum[u]; int res=0; int mid=(l+r)>>1; if(pl<=mid) res+=query(L[u],L[v],l,mid,pl,pr); if(pr>mid) res+=query(R[u],R[v],mid+1,r,pl,pr); return res; } int main(){ int Test;Test=read(); while(Test--){ int n,m;n=read();m=read(); for(int i=1;i<=n;i++){ a[i]=read(); T[i]=update(T[i-1],1,M,a[i]); } int ans=0; while(m--){ int l,r,p,k;l=read();r=read();p=read();k=read(); l=l^ans,r=r^ans,p=p^ans,k=k^ans; int left=0,right=M; while(left<=right){ int mid=(left+right)>>1; if(query(T[l-1],T[r],1,M,max(1,p-mid),min(M,p+mid))>=k){ ans=mid; right=mid-1; } else left=mid+1; } printf("%d\n",ans); } } return 0; }
2019杭电多校赛第四场 HDU6621 K-th Closest Distance 主席树 二分
标签:理解 题目 air distance mod main turn show 完全
原文地址:https://www.cnblogs.com/qingjiuling/p/11298609.html