ZCMU—1956

1956: #515. 「LibreOJ β Round #2」贪心只能过样例

Time Limit: 5 Sec   Memory Limit: 128 MB
Submit: 11   Solved: 6
[ Submit][ Status][ Web Board]

Description

一共有 nnn个数,第 iii 个数 xix_ixi 可以取 [ai,bi][a_i , b_i][ai,bi] 中任意值。
设 S=∑xi2S = \sum{{x_i}^2}S=xi2,求 SSS 种类数。

Input

第一行一个数 nnn
然后 nnn 行,每行两个数表示 ai,bia_i,b_iai,bi

Output

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

Sample Input

5
1 2
2 3
3 4
4 5
5 6

Sample Output

26

HINT

因oj不支持markdown和tex.


若无法正确显示tex数学公式,请使用google chrome浏览器并安装math anywhere插件(**谁改了题面啊**。药丸.jpg

【分析】

f[i][j]表示前i个数能否组成j,那么对于当前存在的第i个区间[l,r],考虑所有存在的f[i-1][j]==1都可以推到f[i][j+k*k];

换种写法就是f[i][j]=f[i-1][j-k*k](l<=k<=r),但是考虑数据范围虽然只有100,但是最终结果最大会有1000000,也就是说f数组的定义需要f[100][1000000],
那么算法复杂度为O(n^5),那么显然是TLE的...但是考虑到f数组中只存0/1表示是否可行,那么就可以用bitset优化一下,
对当前的f[i]可能情况,只要左移k*k位,就是能组成的新情况,然后所有结果取or结果就可以了
//然后这里有一个小优化,因为数据范围有100*100*100*100,这里用滚动数组的方式可以优化内存,当然对这道题目没有影响....

【代码】
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <bitset>
using namespace std;
 
bitset<1001000>a,b;
int main()
{
    int n;
    while (~scanf("%d",&n))
    {
        a.reset();a[0]=1;
        while (n--)
        {
            int x,y;scanf("%d%d",&x,&y);
            b.reset();a<<=(x*x);b|=a;
            for (int i=x+1;i<=y;i++)
            {
                a<<=(i*i-(i-1)*(i-1));
                b|=a;
            }
            a=b;
        }
        printf("%d\n",a.count());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值