Topic link: https: //ac.nowcoder.com/acm/contest/887/E
The meaning of problems: given L [i], R [i], each addition of L [i] ... R [i], the median calculated at this time.
Idea: Since the number of range added to 1e9, first thought to use discrete, here is a point to indicate a range.
Plus a section of the right main purpose is to optimize the process, the range of the last element incorporated into the front of them simulate a moment to understand it.
Then maintain the tree line with the number of elements contained in each node, plus the number represented by a lazy mark laz, then each time a query if the number of elements in the left subtree enough query in the left sub-tree, or in the right subtree Inquire.
Refer to code:
#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\n",query(1,(sum+1)>>1)); } return 0; }