题意: 一开始为空序列 每次加入 L R 之间的数字(包括L,R ) 问中位数为多少
很显然是一个权值线段树 但是R的范围有1e9 比赛的时候没想到离散化QAQ(主要是被那个解密过程给恶心到了 woc明明没有强制在线 还解个锤子迷)
要将两个闭区间改为左闭右开 ( 有点像扫描线) 所以r[i]+1即可
然后就是线段树每个点代表的是一个区间
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define pb push_back #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) typedef pair<int,int>pii; ////////////////////////////////// const int N=800000+10; #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 ll t[N<<2],len[N<<2],b[N<<2],col[N<<2]; void up(int pos) { t[pos]=t[pos<<1]+t[pos<<1|1]; } void build(int l,int r,int pos) { if(l==r){len[pos]=b[l+1]-b[l];return ;} int m=(l+r)>>1; build(lson);build(rson); len[pos]=len[pos<<1]+len[pos<<1|1]; } void down(int pos) { if(!col[pos])return ; col[pos<<1]+=col[pos]; col[pos<<1|1]+=col[pos]; t[pos<<1]+=col[pos]*len[pos<<1]; t[pos<<1|1]+=col[pos]*len[pos<<1|1]; col[pos]=0; } void upsum(int L,int R,int l,int r,int pos) { if(L<=l&&r<=R) { col[pos]++;t[pos]+=len[pos]; return ; } down(pos);int m=l+r>>1; if(L<=m)upsum(L,R,lson); if(R>m)upsum(L,R,rson); up(pos); } ll qsum(ll k,int l,int r,int pos) { if(l==r) { ll temp=t[pos]/len[pos]; return b[l]+1ll*(k-1)/temp; } int m=(l+r)>>1;down(pos); if(t[pos<<1]>=k)return qsum(k,lson); else return qsum(k-t[pos<<1],rson); } ll n,m,x[N],y[N],a1,b1,c1,m1,a2,b2,c2,m2,l[N],r[N],cnt; int main() { cin>>n; cin>>x[1]>>x[2]>>a1>>b1>>c1>>m1; cin>>y[1]>>y[2]>>a2>>b2>>c2>>m2; rep(i,3,n)x[i]=(a1*x[i-1]+b1*x[i-2]+c1)%m1,y[i]=(a2*y[i-1]+b2*y[i-2]+c2)%m2; rep(i,1,n) { l[i]=min(x[i],y[i])+1; r[i]=max(x[i],y[i])+1; r[i]++; b[++cnt]=l[i];b[++cnt]=r[i]; } sort(b+1,b+1+cnt); m=unique(b+1,b+1+cnt)-b-1; build(1,m-1,1); ll sum=0; rep(i,1,n) { int L=lower_bound(b+1,b+1+cnt,l[i])-b; int R=lower_bound(b+1,b+1+cnt,r[i])-b; sum+=r[i]-l[i]; upsum(L,R-1,1,m-1,1); printf("%lld\n",qsum((sum+1)/2,1,m-1,1)); } return 0; }