1. 程式人生 > >LibreOJ β Round #2 B.貪心只能過樣例【Dp+bitset優化】

LibreOJ β Round #2 B.貪心只能過樣例【Dp+bitset優化】

B. 貪心只能過樣例

記憶體限制:256 MiB時間限制:1000 ms標準輸入輸出 題目型別:傳統評測方式:文字比較 轉到題庫提交記錄返回比賽

題目描述

一共有 nnn個數,第 iii 個數 xix_ixi 可以取 [ai,bi][a_i , b_i][ai,bi] 中任意值。
設 S=∑xi2S = \sum{{x_i}^2}S=xi2,求 SSS 種類數。

輸入格式

第一行一個數 nnn
然後 nnn 行,每行兩個數表示 ai,bia_i,b_iai,bi

輸出格式

輸出一行一個數表示答案。

樣例

樣例輸入

5
1 2
2 3
3 4
4 5
5 6

樣例輸出

26

資料範圍與提示

1≤n,ai,bi≤1001 \le n , a_i , b_i \le 1001n,ai,bi100


思路:

暴力Dp轉移需要O(n^5)的時間複雜度。

考慮到這是類似一個揹包的狀態,我們設定dp【i】就是一個bool陣列,表示i這個數字能否湊出來。

那麼對應我們可以O(n^5/64)用bitset優化一下常數。

#include<stdio.h>
#include<string.h>
#include<bitset>
#include<iostream>
using namespace std;
int L[150];
int R[150];
bitset<1000050>a,b,tmp;
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)scanf("%d%d",&L[i],&R[i]);
        a.reset();
        b.reset();
        for(int i=L[1];i<=R[1];i++)
        {
            a[i*i]=1;
        }
        for(int i=2;i<=n;i++)
        {
            b.reset();
            for(int j=L[i];j<=R[i];j++)
            {
                tmp.reset();
                tmp=a<<(j*j);
                b=(b|(tmp));
            }
            a=b;
        }
        printf("%d\n",a.count());
    }
}