问:
n个x,xi 最多可以取Li 到 Ri,求sigma(xi*xi),
n , Li, Ri <= 100
考虑暴力dp
因为和最大为100* 100* 100 = 1e6
枚举n个数
枚举这n个数取的值
枚举每个状态是否能从上个数的状态转移
复杂度 100 * 100 * 100000 = 1e10显然是不行的
可以用bitset优化,因为是集合的形式,位运算相当的快。
a 存上一个状态所有的答案,第i位为1说明到上一个状态前面这些数的和可以表示出i
tmp 存上个状态加上一个数后得到的新的可以表示出来的状态集合
b 是转移时更新用的,每次和tmp或一下,这次的所有数加完就得到了由上个状态转移出来的新状态了 再让a = b即可
//#pragma GCC optimize (2)
//#pragma GCC optimize (3)
//#pragma GCC optimize (Ofast)
#define fastio ios_base::sync_with_stdio(0); cin.tie(NULL);
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)
#define LL long long
#define debug1 cout << "???" << endl;
#define debug2(x) cout << #x << ": " << x << endl;
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e2+7;
const int MAXN = 1e6+7;
int n, maxn, ans, num[N][2];
bitset <MAXN> a, b, tmp;
int main()
{
fastio
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
cin >> n;
rep(i, 1, n)
{
cin >> num[i][0] >> num[i][1];
maxn += num[i][1] * num[i][1];
}
rep(i, num[1][0], num[1][1])
a[i*i] = 1;
rep(i, 2, n)
{
b.reset();
rep(j, num[i][0], num[i][1])
{
tmp = a << j*j;
b = (b|tmp);
}
a = b;
}
rep(i, 1, maxn)
if(a[i]) ans++;
cout << ans << endl;
return 0;
}