LibreOJ β Round #2 515 贪心只能过样例

问:
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值