Loading

P6146 [USACO20FEB]Help Yourself G 组合数学 DP

计算所有线段的所有子集的复杂度的和。

复杂度:线段集合的连通块个数。

连通块:不相交的并

考虑每个线段对前 i - 1个线段的贡献,若不选,则复杂度和不变,若选,则不相交的部分会贡献 2 ^ x 的复杂度。

故每次只需计算x的大小,x的大小可以建立前缀和数组来维护。

void Put(ll x) {
    if (x < 0) putchar('-'), x *= -1;
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}

struct Seg {
    int l, r;
    friend bool operator < (const Seg& a, const Seg& b) {
        if (a.l == b.l) return a.r < b.r;
        return a.l < b.l;
    }
};

Seg s[maxn];
ll sum[2 * maxn];
int main() {
    int n = readint();
    int x, y;
    for (int i = 0; i < n; i++) {
        x = readint();
        y = readint();
        s[i].l = x, s[i].r = y;
        sum[y]++;
    }
    sort(s, s + n);
    for (int i = 1; i < s[n - 1].r; i++) sum[i] += sum[i - 1];
    ll pre = 1;
    ll res = 1;
    for (int i = 1; i < n; i++) {
        res = 2 * pre + ksm(2, sum[s[i].l - 1], MOD);
        res %= MOD;
        pre = res;
    }
    Put(res);
}

 

posted @ 2020-08-17 19:57  MQFLLY  阅读(126)  评论(0编辑  收藏  举报