NC17193 简单瞎搞题

题目链接

题目

题目描述

一共有 n个数,第 i 个数是 xi

xi 可以取 [li , ri] 中任意的一个值。

\(S = \sum{{x_i}^2}\) ,求 S 种类数。

输入描述

第一行一个数 n。
然后 n 行,每行两个数表示 li,ri。

输出描述

输出一行一个数表示答案。

示例1

输入

5
1 2
2 3
3 4
4 5
5 6

输出

26

备注

1 ≤ n , li , ri ≤ 100

题解

知识点:背包dp,STL。

多重背包思路,每个整数 \(x_i\) 当作 \([l_i,r_i]\) 个不加区分的 \(1\) 组成,再用一个数组 \(dp[i][j]\) 表示为考虑到 \(x_i\)\(j\) 是否出现过。转移方程为:

\[dp[i][k] |= dp[i-1][k-j^2],j\in [l_i,r_i] \]

可以用 bitset 常数优化时间和空间。

时间复杂度 \(O(n(r-l) \cdot \frac{10^6}{32})\)

空间复杂度 \(O(n \cdot \frac{10^6}{32})\)

代码

#include <bits/stdc++.h>

using namespace std;

bitset<1000007> dp[107];

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    dp[0][0] = 1;
    for (int i = 1;i <= n;i++) {
        int l, r;
        cin >> l >> r;
        for (int j = l;j <= r;j++) {
            dp[i] |= dp[i - 1] << j * j;
        }
    }
    cout << dp[n].count() << '\n';
    return 0;
}
posted @ 2022-08-14 17:51  空白菌  阅读(26)  评论(0编辑  收藏  举报