题意

求出所以子集中最小没有出现的正整数之和。

分析

我们可以考虑一个元素的贡献,我们先考虑如果这个数 可以作为答案,那么 的每个元素至少选取了一次。那么根据乘法原理, 的总方案为 表示 这个数出现的次数。那么 的元素,可以选也可以不选总的方案数为 。上面的指数也可以通过前缀和维护。那么当元素的取值不连续时,我们就可以退出了,因为无论怎么选,答案都不能比这个大了。由于是考场写的,有点丑。

代码

//  sto xzc orz
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
    return f ? -x : x;
}
const int N = 5e5 + 1000,mod = 20000311;
int ksm(int a,int b) {
    int x = 1;for(;b;b >>= 1,a = a * 1ll * a % mod) {
        if(b & 1) x = x * 1ll * a % mod;
    }return x;
}
int A[N],n,B[N],C[N],fac[N],ifac[N],tot,M = 5e5;
int main() {
    n = read();
    for(int i = 1;i <= n;i++) A[i] = B[i] = read();
    sort(B+1,B+1+n);
    tot = unique(B + 1,B + 1 + n) - B - 1;
    for(int i = 1;i <= n;i++) if(A[i] <= M) C[A[i]]++;
    int ans = 0,L = 1,res = 0;
    for(int i = 1;;i++) {
        auto it = lower_bound(B + 1,B + 1 + tot,i);
        if((*it) != i) {ans = (ans + (L *1ll* ksm(2,n - res)%mod * 1ll * i % mod)) % mod;break;}
        else ans = (ans + (L *1ll* ksm(2,n - res - C[i])%mod * 1ll * i % mod)) % mod;
        L = (L * 1ll * ((ksm(2,C[i])) - 1 + mod)% mod ) % mod;
        res += C[i];
    }
    cout << ans << endl;
    return 0;
}