明白之后 5min 就写好了…自闭…
这题的题意是问你 \([L,R]\) 区间的数字不能构成的数字的最小值…
首先考虑 如果 \([1,x]\) 可以被表示
那么加入一个 \(a_i\) 显然 \([1,x+a_i]\) 都可以被表示
有什么好办法呢
当然有 \(O(q * \sum_{i\in[L,R]}{a_i}*[R-L+1])\)
(雾)
区间求和问题啥的考虑主席树,首先我不会证明复杂度,是因为我菜/kk
还是一样的套路 讨论 \([1,x]\)
对于区间求 \(\sum_{i\in[L,R]}[a_i<=ans]\)
\([ans\)初值是1\(]\)
显然此时 \([1,ans-1]\) 都可以表示出来 所以考虑扩大区间使得这个\(res = \sum_{i\in[L,R]}[a_i<=ans]\)
如果值比 \(ans\) 小肯定是不可以构成 \(ans+1\) 的 所以无需扩展…
#include<bits/stdc++.h> using ll = long long ; using namespace std ; int read() { int x = 0 , f = 1 ; char c = getchar() ; while(c < '0' || c > '9') { if(c == '-') f = -1 ; c = getchar() ; } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c & 15) ; c = getchar() ; } return x * f ; } const int N = 1e5 + 10 ; const int MAXN = N << 5 ; const int INF = 1e9 ; int n , a[N] , rt[N] , ls[MAXN] , rs[MAXN] , sum[MAXN] , cnt = 0 ; void upd(int pre , int & o , int l , int r , int pos , int val) { ls[o = ++ cnt] = ls[pre] ; rs[o] = rs[pre] ; sum[o] = sum[pre] + val ; if(l == r) return ; int mid = l + r >> 1 ; if(pos <= mid) upd(ls[pre] , ls[o] , l , mid , pos , val) ; else upd(rs[pre] , rs[o] , mid + 1 , r , pos , val) ; } int query(int a , int b , int l , int r , int L , int R) { if(a <= l && r <= b) return (sum[R] - sum[L]) ; int mid = l + r >> 1 , ans = 0 ; if(a <= mid) ans += query(a , b , l , mid , ls[L] , ls[R]) ; if(b > mid) ans += query(a , b , mid + 1 , r , rs[L] , rs[R]) ; return ans ; } signed main() { n = read() ; for(int i = 1 ; i <= n ; i ++) a[i] = read() ; for(int i = 1 ; i <= n ; i ++) upd(rt[i - 1] , rt[i] , 1 , INF , a[i] , a[i]) ; int m = read() ; while(m --) { int L = read() , R = read() , ans = 1 ; while(1) { int res = query(1 , ans , 1 , INF , rt[L - 1] , rt[R]) ; if(res >= ans) ans = res + 1 ; else break ; } printf("%d\n" , ans) ; } return 0 ; }