G smaller Sum:
题目大意:
思路解析:
这道题是一个在线查询,要求 Li -- Bi 并且 小于等于 Xi的元素之和,如果x是固定的,那我们可以很容易的想到使用线段树求解,但是现在X不是固定的,但是没有修改组内元素,即元素始终无变化, 那我们是不是可以对于每一个X建一个线段树,那这里我们想到主席树,每个结点维护 a<= <=b的元素之和,并且在对每个X建树时,相同情况可以复用。
代码实现:
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
static int maxn = (int) 2e5 + 5;
static int[] rt = new int[maxn];
static int[] ls = new int[maxn << 5];
static int[] rs = new int[maxn << 5];
static long[] t = new long[maxn << 5];
static int tot = 0;
static int INF = (int) 1e9;
public static void main(String[] args) throws IOException {
int n = f.nextInt();
for (int i = 1; i <= n; i++) {
long x = f.nextInt();
rt[i] = upd(x, rt[i], rt[i-1], 0, INF);
}
long lst = 0;
int q = f.nextInt();
for (int i = 0; i < q; i++) {
long l = f.nextLong();
long r = f.nextLong();
long x = f.nextLong();
l ^= lst;
r ^= lst;
x ^= lst;
lst = qry(0, x, rt[(int) r], rt[(int) l-1], 0, INF);
out.println(lst);
}
out.flush();
out.close();
br.close();
}
public static int upd(long x, int cur, int pre, int l, int r){
if (cur == 0) cur = ++tot;
if (l == r){
t[cur] = t[pre] + x;
return cur;
}
int mid = (l + r) >> 1;
if (x <= mid) {rs[cur] = rs[pre]; ls[cur] = upd(x, ls[cur], ls[pre], l, mid);}
else{ls[cur] = ls[pre]; rs[cur] = upd(x, rs[cur], rs[pre], mid+1, r);}
t[cur] = t[ls[cur]] + t[rs[cur]];
return cur;
}
static long qry(int nl, long nr, int cur, int pre, int l ,int r){
if (nr >= r) return t[cur] - t[pre];
int mid = (l + r) >> 1;
long res = 0;
if (nl <= mid) res += qry(nl, nr, ls[cur], ls[pre], l, mid);
if (nr > mid) res += qry(nl,nr,rs[cur],rs[pre],mid+1,r);
return res;
}
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static Input f = new Input(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static class Input {
public BufferedReader reader;
public StringTokenizer tokenizer;
public Input(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine() {
String str = null;
try {
str = reader.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return str;
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public Double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}
}