bzoj2734 HNOI2012 集合選數

2021-07-10 22:49:26 字數 1718 閱讀 5737

time limit: 10 sec memory limit: 128 mb

submit: 889 solved: 523

[submit][status][discuss]

description

《集合論與圖論》這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集:若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題:對於任意乙個正整數 n≤100000,如何求出 的滿足上述約束條件的子集的個數(只需輸出對 1,000,000,001 取模的結果),現在這個問題就 交給你了。

input

只有一行,其中有乙個正整數 n,30%的資料滿足 n≤20。

output

僅包含乙個正整數,表示有多少個滿足上述約束條件 的子集。

sample input

4
sample output

8
【樣例解釋】

有8 個集合滿足要求,分別是空集,,,,,,,。

很巧妙的乙個構造方法構造乙個矩陣,使得f[

i][j

+1]=

f[i]

[j]∗

3,f[

i+1]

[j]=

f[i]

[j]∗

2 這樣構造出矩陣之後,矩陣中的乙個元素和他四個方向上的元素就不能同時選。

n的範圍是105

,如果把每一行都壓成乙個狀態的話,那麼最多只有lo

g3(10

5)≈11

列,lo

g2(10

5)≈17

行。轉移的時候就列舉所有狀態就行了。

有乙個問題需要注意,不是所有數都能放在乙個矩陣裡的,所以要構建很多次矩陣。

時間複雜度:o(

17∗211

∗211)

≈7∗10

7

#include

#include

#include

using

namespace

std;

#define ll long long

#define mod 1000000001

const

int n=20;

const

int m=100010;

bool flag[m];

int n,f[n][1

inline

int calc(int x)

for(m=i,j=1;j<=n;++j)

}for(i=1;i<=m;++i)

for(i=0;i<(1

>1))&&!(limit[1]&i)) f[1][i]=1;

for(i=2;i<=m;++i)

for(j=0;j<(1

>1))&&!(limit[i]&j))

for(f[i][j]=0,k=0;k<(1

>1))&&!(limit[i-1]&k)&&!(k&j))

f[i][j]=(f[i][j]+f[i-1][k])%mod;

int sum=0;

for(i=0;i<(1

>1))&&!(i&limit[m])) sum+=f[m][i];

return sum;

}int main()

bzoj2734 HNOI2012 集合選數

time limit 10 sec memory limit 128 mb submit 831 solved 487 submit status discuss 集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同...

bzoj2734 HNOI2012 集合選數

題目鏈結 集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題 對於任意乙個正整數 n 100000,如何求出 的滿足上述約束條件的子集的個數 只需輸出對 1...

BZOJ2734 HNOI2012 集合選數

description 求出集合中,滿足 諾x在該集合中,2x與3x不在集合。的所有子集的個數。對答案mod 1000000001。題解這個題目很要思維了,反正我沒想出來,但看了題解十分佩服。我們構造乙個矩陣,x3x 9x.3j x 2x6x 18x.2i x 2i 3jx 可以發現,滿足要求的子集...