Codechef FRBSUM 解题报告

题目思路中比较难的一点是一个结论:如果使用集合S的子集可以构造出[0,s]的所有数字, 那么设S集合之外全集之内存在一个数字x,那么若把数字x加入到集合S中,则可以构造出[x,s+x]的全部数字。 若存在的最小x > 1, 则 s+1为不可构造解。

这个题目基本上是基于上面的这个结论来解决的。结论比较容易证明。 对于任何一个可能的数组, 0 都是一个必定可以构造的值, 所以从0开始, 不断判断在当前的[0, s]的构造存在的情况下, s+1是否可以构造即可。

写代码时候遇到了坑。 由于 a[i] <= 1e9, 所以我无脑离散化了一下, 于是TLE了。 看别人的解题报告后发现, 不离散化AC。

代码如下:

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 #define mp make_pair
 4 #define lson l,m
 5 #define rson m+1,r
 6 typedef long long ll;
 7 using namespace std;
 8 const int maxn = 1e5+10;
 9 const int maxv = 1e9;
10 const int maxtree = maxn*32;
11 int a[maxn], Hash[maxn], n;
12 int T[maxn], val[maxtree], L[maxtree], R[maxtree], tot;
13 
14 int build(int l, int r){
15     int rt = ++tot;
16     val[rt] = 0;
17     if(l < r){
18         int m = (l+r)/2;
19         L[rt] = build(lson);
20         R[rt] = build(rson);
21     }
22     return rt;
23 }
24 
25 int update(int pre, int p, int v, int l, int r){
26     int rt = ++tot;
27     L[rt] = L[pre], R[rt] = R[pre];
28     val[rt] = val[pre] + v;
29     if(l < r){
30         int m = (l+r)/2;
31         if(p <= m) L[rt] = update(L[pre], p, v, lson);
32         else R[rt] = update(R[pre], p, v, rson);
33     }
34     return rt;
35 }
36 
37 int query(int srt, int trt, int begin, int end, int l, int r){
38     if(begin <= l && r <= end) return val[trt] - val[srt];
39     int m = (l+r)/2, res = 0;
40     if(begin <= m) res += query(L[srt], L[trt], begin, end, lson);
41     if(end > m) res += query(R[srt], R[trt], begin, end, rson);
42     return res;
43 }
44 
45 int main() {
46     int m, l, r;
47     scanf("%d", &n);
48     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
49     for(int i = 1; i <= n; i++) T[i] = update(T[i-1], a[i], a[i], 1, maxv);
50     scanf("%d", &m);
51     while(m--){
52         scanf("%d%d", &l, &r);
53         int _mx = 0;
54         for(int i = 1; ; i = _mx + 1){
55             _mx = query(T[l-1], T[r], 1, i, 1, maxv);
56             if(_mx < i){
57                 printf("%d
", i);
58                 break;
59             }
60         }
61     }
62 }
原文地址:https://www.cnblogs.com/zzhzz/p/8659841.html