题目链接:点我啊╭(╯^╰)╮
题目大意:
每次加入一个区间的数,求中位数
解题思路:
区间离散化
线段树每个节点表示离散之后的区间的数目总和
注意离散区间的时候右端点要加一
最后线段树二分完之后要处理一下
核心:线段树处理离散区间
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 998244353;
const int maxn = 2e6 + 10;
int n, a1, b1, c1, m1;
int a2, b2, c2, m2;
int ls[maxn], ans[maxn];
int l[maxn], r[maxn], x[maxn], y[maxn];
ll t[maxn<<2], lazy[maxn<<2], len[maxn], id[maxn];
void pushup(int rt){
t[rt] = t[rt<<1] + t[rt<<1|1];
}
void pushdown(int rt){
if(lazy[rt]){
t[rt<<1] += lazy[rt] * len[rt<<1];
t[rt<<1|1] += lazy[rt] * len[rt<<1|1];
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
}
void build(int l, int r, int rt){
t[rt] = lazy[rt] = 0;
if(l==r) {
len[rt] = id[l];
return;
}
int m = l + r >> 1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
len[rt] = len[rt<<1] + len[rt<<1|1];
}
void update(int L,int R,int l,int r,int rt){
if(l>R || r<L) return;
if(L<=l && r<=R){
t[rt] += len[rt];
lazy[rt]++;
return ;
}
pushdown(rt);
int m = l + r >> 1;
update(L,R,l,m,rt<<1);
update(L,R,m+1,r,rt<<1|1);
pushup(rt);
}
int query(ll tot, int l, int r, int rt){
if(l==r){
ll num = t[rt] / len[rt];
return ls[l] + (tot - 1) / num;
}
pushdown(rt);
int m = l + r >> 1;
if(t[rt<<1]>=tot) return query(tot,l,m,rt<<1);
else return query(tot-t[rt<<1],m+1,r,rt<<1|1);
}
int main() {
scanf("%d", &n);
scanf("%d%d%d%d%d%d", &x[1], &x[2], &a1, &b1, &c1, &m1);
scanf("%d%d%d%d%d%d", &y[1], &y[2], &a2, &b2, &c2, &m2);
l[1] = min(x[1], y[1]) + 1, r[1] = max(x[1], y[1]) + 1;
l[2] = min(x[2], y[2]) + 1, r[2] = max(x[2], y[2]) + 1;
for(int i=3; i<=n; i++){
x[i] = (1ll*a1*x[i-1] + 1ll*b1*x[i-2] + c1) % m1;
y[i] = (1ll*a2*y[i-1] + 1ll*b2*y[i-2] + c2) % m2;
l[i] = min(x[i], y[i]) + 1, r[i] = max(x[i], y[i]) + 1;
}
for(int i=1; i<=n; i++) ls[i] = l[i], ls[i+n] = r[i] + 1;
sort(ls+1, ls+1+n+n);
int cnt = unique(ls+1, ls+1+n+n) - ls - 1;
for(int i=1; i<=cnt; i++) id[i] = ls[i+1] - ls[i];
id[cnt] = 1;
build(1,cnt,1);
for(int i=1; i<=n; i++){
int u = lower_bound(ls+1, ls+cnt+1, l[i]) - ls;
int v = lower_bound(ls+1, ls+cnt+1, r[i]+1) - ls;
update(u,v-1,1,cnt,1);
ll sum = (t[1] + 1) / 2;
ans[i] = query(sum,1,cnt,1);
}
for(int i=1; i<=n; i++) printf("%d\n", ans[i]);
}