题目链接:https://ac.nowcoder.com/acm/contest/887/E
题意:给出L[i],R[i],每次添加L[i]...R[i],求出此时的中位数。
思路:因为添加的数范围为1e9,首先想到要用离散化,这里是用一个点来表示一个区间。
将右区间加一的主要目的是优化处理,将区间最后一个元素并入到前面,自己模拟一下就能明白啦。
然后用线段树维护每个节点所包含的元素个数,用懒惰标记laz表示加的次数,然后每次查询时若左子树的元素个数足够则在左子树查询,否则在右子树查询。
详见代码:
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef long long LL; const int maxn=4e5+5; struct node{ int l,r,laz; LL sz; }tr[maxn<<3]; int n; LL X[maxn],Y[maxn],A1,A2,B1,B2,C1,C2,M1,M2; vector<int> vc; void build(int v,int l,int r){ tr[v].l=l,tr[v].r=r; if(l==r){ return; } int mid=(l+r)>>1; build(v<<1,l,mid); build(v<<1|1,mid+1,r); } void pushdown(int v){ tr[v<<1].sz+=(vc[tr[v<<1].r+1]-vc[tr[v<<1].l])*tr[v].laz; tr[v<<1].laz+=tr[v].laz; tr[v<<1|1].sz+=(vc[tr[v<<1|1].r+1]-vc[tr[v<<1|1].l])*tr[v].laz; tr[v<<1|1].laz+=tr[v].laz; tr[v].laz=0; } void update(int v,int l,int r){ if(l<=tr[v].l&&r>=tr[v].r){ tr[v].sz+=(vc[tr[v].r+1]-vc[tr[v].l]); tr[v].laz+=1; return; } if(tr[v].laz) pushdown(v); int mid=(tr[v].l+tr[v].r)>>1; if(l<=mid) update(v<<1,l,r); if(r>mid) update(v<<1|1,l,r); tr[v].sz=tr[v<<1].sz+tr[v<<1|1].sz; } int query(int v,LL k){ if(tr[v].l==tr[v].r){ int tmp=tr[v].sz/(vc[tr[v].l+1]-vc[tr[v].l]); return vc[tr[v].l]+(k-1)/tmp; } if(tr[v].laz) pushdown(v); if(k<=tr[v<<1].sz) return query(v<<1,k); else return query(v<<1|1,k-tr[v<<1].sz); } int main(){ scanf("%d",&n); scanf("%lld%lld%lld%lld%lld%lld",&X[1],&X[2],&A1,&B1,&C1,&M1); scanf("%lld%lld%lld%lld%lld%lld",&Y[1],&Y[2],&A2,&B2,&C2,&M2); for(int i=3;i<=n;++i){ X[i]=(A1*X[i-1]%M1+B1*X[i-2]%M1+C1)%M1; Y[i]=(A2*Y[i-1]%M2+B2*Y[i-2]%M2+C2)%M2; } for(int i=1;i<=n;++i){ ++X[i],++Y[i]; if(X[i]>Y[i]) swap(X[i],Y[i]); vc.push_back(X[i]),vc.push_back(Y[i]+1); } sort(vc.begin(),vc.end()); vc.erase(unique(vc.begin(),vc.end()),vc.end()); LL sum=0; int cnt=vc.size(); build(1,0,cnt-1); for(int i=1;i<=n;++i){ sum+=Y[i]-X[i]+1; int x,y; x=lower_bound(vc.begin(),vc.end(),X[i])-vc.begin(); y=lower_bound(vc.begin(),vc.end(),Y[i]+1)-vc.begin(); update(1,x,y-1); printf("%d ",query(1,(sum+1)>>1)); } return 0; }