每个线段树节点需要保存四个值,ls,rs,min,tag
由于空间不够 所以把他们压缩成一个unsinged long long
t[x] = (ls * N + rs) * T + val + tag
t[x] % T 即可得到val + tag, ls = t[x] / T / N, rs = t[x] / T % N
进行标记永久化过后可以用左右儿子的值解出自己的val,再解出tag
然后就卡着内存过去了
黑科技简直可怕
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
#define mp make_pair
#define fir first
#define sec second
#define sqr(x) ((x)*(x))
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const int MAXN = 200000;
int n, m, rt[MAXN+10], Q;
pii a[MAXN+10];
struct Seg_Tree {
static const int N = 8000000 + 10;
static const int T = MAXN + 3;
int ncnt;
ull t[N];
inline void calc_s(const bool &nl, const bool &nr, ull x, int &ls, int &rs, int &tag) {
int s = x % T;
ls = x / T / N; rs = x / T % N;
tag = s - min((nl ? ls : t[ls] % T), (nr ? rs : t[rs] % T));
}
inline ull calc(const int &ls, const int &rs, const int &val) {
return (1ull * ls * N + rs) * T + val;
}
void ins(const int &last, int &u, const int &L, const int &R, const int &l, const int &r) {
if(L == R) {
u = last+1;
return ;
}
t[u = ++ncnt] = t[last];
if(l <= L && R <= r) {
t[u]++;
return ;
}
int mid = (L+R) >> 1, ls, rs, val, lson = 0, rson = 0;
calc_s((L == mid), (R == mid+1), t[u], ls, rs, val);
if(l <= mid) ins(ls, lson, L, mid, l, r);
if(r > mid) ins(rs, rson, mid+1, R, l, r);
if(!lson) lson = ls;
if(!rson) rson = rs;
val += min(((L == mid) ? lson : t[lson] % T), ((R == mid+1) ? rson : t[rson] % T));
t[u] = calc(lson, rson, val);
}
int query(const int &u, const int &L, const int &R, const int &l, const int &r) {
if(L == R) return u;
if(!u) return 0;
if(l <= L && R <= r) return t[u] % T;
int mid = (L+R) >> 1, ls, rs, val, ret = N;
calc_s((L == mid), (mid+1 == R), t[u], ls, rs, val);
if(l <= mid) ret = min(ret, query(ls, L, mid, l, r));
if(r > mid) ret = min(ret, query(rs, mid+1, R, l, r));
return ret + val;
}
inline void build() {
for(int i = 1; i <= n; i++)
ins(rt[i-1], rt[i], 1, n-m+1, max(1, a[i].sec-m+1), a[i].sec);
}
} seg;
int main() {
SF("%d%d", &n, &m);
for(int i = 1; i <= n; i++) SF("%d", &a[i].fir), a[i].sec = i;
sort(a+1, a+1+n);
seg.build();
SF("%d", &Q);
int ans = 0;
for(int i = 1; i <= Q; i++) {
int x, l, r;
SF("%d%d%d", &l, &r, &x);
x ^= ans;
x = lower_bound(a+1, a+1+n, mp(x, 0)) - a;
if(x == 1) ans = 0;
else ans = seg.query(rt[x-1], 1, n-m+1, l, r);
PF("%d\n", ans);
}
return 0;
}