目录
牛牛的凑数游戏:
题目大意:
思路解析:
代码实现:
牛牛的凑数游戏:
题目大意:
思路解析:
我们可以很容易一个区间是否会存在1,那么我们想如果存在1,且有3个1,那我们一定可以组成 1,2,3,那么为出现的数为4,如果这个区间还有一个四,我们可以发现我们一定可以组成5,6,7,那我们如果这个区间还有 a个3,b个2,那我们发现我们一定可以组成 [1,3+4+3*a+2*b],这是因为任意一个数都可以表示为 n = 4 * k + m, 0<=m<=3,那我们假设组成的3+4+3*a+2*b == 17,那么下一次的数一定可以表示为 n = 17 * k + m ( 0<=m<=16)..... 这个问题就转化为了 计算[1,1]的和 记作 a, 计算[1,a+1]的和 记住b,计算[1,b+1]的和。。。一直迭代下去最后一定会因为某些数字的未出现而结束。
那么问题变为了查询 [l,r]这个区间 里面数字属于 [L,R]这个范围的和为多少。这个可以使用主席树实现。
代码实现:
import java.io.*;
import java.math.BigInteger;
import java.util.*;public class Main {static int MAXN = (int) 1e5 + 5;static int tot = 0;static int[] a = new int[MAXN];static int[] root = new int[MAXN];static Node[] t = new Node[MAXN * 32];static int ans = 0;static int INF = (int) 1e9 +100;public static void main(String[] args) {int n = f.nextInt(); int m = f.nextInt();t[0] = new Node();for (int i = 1; i <= n; i++) {a[i] = f.nextInt();root[i] = ins(root[i], root[i - 1], 1, INF, a[i]);}while (m > 0){int l = f.nextInt();int r = f.nextInt();long cur = 0, res = 0;do {cur = res + 1;res = qry(root[l - 1], root[r], 1, INF, 1, Math.min(cur, INF));}while (cur <= res);System.out.println(cur);m--;}}public static long qry(int s, int e, int l, int r, int L, long R){if (L <= l && R >= r) return t[e].sum - t[s].sum;long res = 0;int mid = (l + r) >> 1;if (L <= mid) res += qry(t[s].l, t[e].l, l, mid, L, R);if (R > mid) res += qry(t[s].r, t[e].r, mid+1, r, L, R);return res;}public static int ins(int p, int q, int l, int r, int x){p = ++tot;t[p] = new Node(t[q]);t[p].sum += x;if (l == r) return p;int mid = (l + r) >> 1;if (x <= mid) t[p].l = ins(t[p].l, t[q].l, l, mid, x);else t[p].r = ins(t[p].r, t[q].r, mid+1, r, x);return p;}static class Node{int l, r;long sum;public Node(Node node) {this.l = node.l;this.r = node.r;this.sum = node.sum;}public Node(){}}static PrintWriter w = 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());}}
}