1. 程式人生 > >LibreOJ 515 貪心只能過樣例

LibreOJ 515 貪心只能過樣例

字節數 鏈接 open soft 取值 bit 但是 運算 統計

題目鏈接:https://loj.ac/problem/515

題意:

  給n(測試數據全是100)個數,第i個數x的取值可以在[a,b](1<=a,b<=100),求sigma(x*x)的取值有多少種。

題解:

  這道題很容易得出一個O(n^5)的復雜度的一個dp(暴力),但是很明顯這個復雜度是不行的。

  這道題可以產生的最大的數是100*100*100=1e6,於是我們可以借助一個叫做bitset的東西來優化一下我們的dp(暴力)。

   bitset可以看做一個bool數組(每一位都是0/1),也可以當成一個二進制表示的數(可以進行位運算),biset作為運算時的復雜度大約是O(N/機器字節數)。借助這三點,我們就可以把這道題優化到O(n^5/128)了。

  我們開一個1000000的bitset,將其每一位代表一個數字(第0位代表0,第1位代表1……),用1表示當前數存在,表示0當前數不存在,每次加一個數x就相當於每個位置左移x位。在以後統計一下最後有多少個1就行了。。

技術分享
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const double eps = 1e-10;
const int maxn = 1e5 + 100;
bitset<1000011> dp[2];
int l,r,pre,now,n;
int
main() { #ifdef ac freopen("in.txt" , "r" , stdin); freopen("out.txt" , "w" , stdout); #endif dp[0][0]=1; pre=now=0; cin >> n; for(int i=1;i<=n;++i) { now^=1; dp[now]=0; cin >> l >> r; for(int j=l;j<=r;++j) dp[now]|=dp[pre]<<(j*j); pre
^=1; } cout << dp[now].count() << endl; return 0; }
View Code

BTW:loj的評測雞跑得好快,stl大法真的好強

LibreOJ 515 貪心只能過樣例