1. 程式人生 > >「LibreOJ β Round #2」貪心只能過樣例 [bitset]【STL】

「LibreOJ β Round #2」貪心只能過樣例 [bitset]【STL】

題目連結:https://loj.ac/problem/515
——————————————————————————————————

515. 「LibreOJ β Round #2」貪心只能過樣例

記憶體限制:256 MiB 時間限制:1000 ms
標準輸入輸出
題目型別:傳統
評測方式:文字比較
上傳者: nzhtl1477

題目描述

一共有 n個數,第 i 個數 xi可以取 [ai,bi]中任意值。
S=xi2,求 S 種類數。

輸入格式
第一行一個數 n
然後 n 行,每行兩個數表示 ai,bi

輸出格式
輸出一行一個數表示答案。
樣例
樣例輸入

5
1 2
2 3
3 4
4 5
5 6
樣例輸出

26
資料範圍與提示
1n,ai,bi100
——————————————————————————————————
其實這個題目很好想,

顯然S的範圍在[1,106] ,

我們用一個數組標記一下那個位置的值存在,然後就好了

過程很簡但維護一下即可,
但是複雜度是O(ni=1{biai}×106)

然後當時採取了用兩個棧+一個標記陣列維護的想法 應該能去掉很多空狀態,

寫了一發但是還是TLE了

最後聽說是用bitset這種東西來維護

其實就是一個可定義長度的01集合

經過內部演算法優化了時間和空間複雜度

可以當成一個可變長度的整形來用

支援整形位運算子

本題就一樣
x21<<(x2)來標記

x2+y21<<(x2+y2)來標記

很容易證明它的正確性

附本題程式碼
——————————————————————————————————

#include <bits/stdc++.h>
typedef long long int LL;
using namespace std;
#define abs(x) ((x)>0?(x):-(x))
#define rep(x,a,b) for(int x=(a),end=(b);x<=end;x++)
const int N = 1e4+7; const int MOD = 1e9+7; /*****************************************************************/ int n; bitset<1010101>f[2]; int main(){ scanf("%d",&n); f[0][0]=1; for(int i=1,l,r;i<=n;i++){ scanf("%d%d",&l,&r); rep(j,l,r) f[i&1] |= f[!(i&1)] << (j*j); f[!(i&1)].reset(); } printf("%d\n",f[(n&1)].count()); return 0; }