涉及一個很複雜的離散化和線段樹的區間更新區間查詢,目前代碼看不懂,需要時間再研究
xls代碼:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 8e5 + 10;
ll sum[maxn * 4];
int S[maxn], L[maxn], R[maxn], tag[maxn * 4], n, sz, S2[maxn];
#define ls o * 2
#define rs o * 2 + 1
#define m (l + r) / 2
void pushdown(int o, int l, int r) {
if (tag[o] == 0)
return;
tag[ls] += tag[o]; tag[rs] += tag[o];
sum[ls] += tag[o] * (S2[m] - S2[l - 1]);
sum[rs] += tag[o] * (S2[r] - S2[m]);
tag[o] = 0;
}
void up(int o, int l, int r, int ql, int qr) {
if (l >=ql && r <= qr) {
sum[o] += S[r] - S[l - 1];
//printf("l = %d r = %d Sl = %d Sr = %d\n", l - 1, r, S[l - 1], S[r]);
tag[o]++;
return;
}
pushdown(o, l, r);
if (ql <= m)
up(ls, l, m, ql, qr);
if (qr > m)
up(rs, m + 1, r, ql, qr);
sum[o] = sum[ls] + sum[rs];
}
int qu(int o, int l, int r, ll v) {
if (l == r) {
int k = sum[o] / (S2[r] - S2[l - 1]);
return (v + k - 1)/ k + S[l - 1];
}
pushdown(o, l, r);
if (sum[ls] < v)
return qu(rs, m + 1, r, v - sum[ls]);
return qu(ls, l, m, v);
}
ll X[maxn], Y[maxn];
void init() {
ll A1, B1, C1, M1;
ll A2, B2, C2, M2;
cin>>n;
cin>>X[1]>>X[2]>>A1>>B1>>C1>>M1;
cin>>Y[1]>>Y[2]>>A2>>B2>>C2>>M2;
for (int i = 1; i <= n; i++) {
if (i > 2) {
X[i] = (A1 * X[i - 1] + B1 * X[i - 2] + C1) % M1;
Y[i] = (A2 * Y[i - 1] + B2 * Y[i - 2] + C2) % M2;
}
L[i] = min(X[i], Y[i]);
R[i] = max(X[i], Y[i]) + 1;
// printf("L = %d R = %d\n", L[i] + 1, R[i]);
S[++sz] = L[i];
S[++sz] = R[i];
}
sort(S + 1, S + 1 + sz);
sz = unique(S + 1, S + 1 + sz) - S - 1;
for (int i = 1; i <= sz; i++)
S2[i] = S2[i - 1] + S[i] - S[i - 1];
}
int main() {
init();
for (int i = 1; i <= n; i++) {
L[i] = lower_bound(S + 1, S + 1 + sz, L[i]) - S;
R[i] = lower_bound(S + 1, S + 1 + sz, R[i]) - S;
up(1, 1, sz, L[i] + 1, R[i]);
ll v = sum[1] / 2;
if (sum[1] & 1)
v++;
//printf("v = %lld sum = %lld L = %d R = %d XL = %d XR = %d\n", v, sum[1], L[i], R[i], S[L[i]], S[R[i]]);
printf("%d\n", qu(1, 1, sz, v));
}
}