简单瞎搞题

链接

https://ac.nowcoder.com/acm/contest/5556/E

题目

链接:https://ac.nowcoder.com/acm/contest/5556/E
来源:牛客网

一共有 n个数,第 i 个数是 (x_i)
(x_i) 可以取 ([l_i , r_i]) 中任意的一个值。
(S=∑x_i^2),求 (S) 种类数。
输入描述:
第一行一个数 n。
然后 (n) 行,每行两个数表示 (l_i,r_i)

输出描述:
输出一行一个数表示答案。
示例
输入
复制

5
1 2
2 3
3 4
4 5
5 6

输出
复制

26

备注:
(1 ≤ n , l_i , r_i ≤ 100)

思路

本质问题是一个01背包凑数问题,但是如果枚举物品(区间)个数,物品(区间内的数),背包容量((1-1000000))肯定会超时,所以需要使用bitset优化。

bitset<1000010> bs;

bs[x]=1表示x这个数可以被凑出来,状态转移就是:

bs[i]|=bs[i-1]<<j*j;

表示上一轮凑出来的数左移(j*j)位,即上一轮凑出来的数加上(j*j),就表示到这一轮可以凑出来的数。
最后bs[n]中1的个数就是可以凑数来数的个数。

代码

#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;
int n;
bitset<1000010> ans,tmp;
int main() {
    scanf("%d",&n);
    ans[0]=1;
    for(int i=1;i<=n;++i){
    	int l,r;
    	cin>>l>>r;
    	tmp.reset();
    	for(int j=l;j<=r;++j){
    	    tmp|=ans<<(j*j);
	}
	ans=tmp;
    }
    cout<<ans.count()<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12833301.html