數字DP 樹狀陣列

2021-08-20 12:13:04 字數 2237 閱讀 7265

考慮如何計算f[

l][r

] f[l

][r]

。很顯然,可以分別計算l,

r l,r

的二進位制中1的個數,然後減去(最大公共字首的1的個數)*2。

考慮如何統計每一對l,

r l,r

的最大字首中1的個數,可以用數字dp。記f

[i][

j][1

/0][

1/0]

f [i

][j]

[1/0

][1/

0]

表示前i i

位,最大公共字首中1的個數為

j' role="presentation">jj,

l l

是/否等於

r' role="presentation">rr,

r r

是/否等於

n' role="presentation">n

n的方案數。這樣,所有數對的最大公共字首中1的個數

t t

顯然就是∏(

j∗f[

len]

[j][

0][1

]+f[

len]

[j][

0][0

])' role="presentation">∏(j

∗f[l

en][

j][0

][1]

+f[l

en][

j][0

][0]

)∏(j

∗f[l

en][

j][0

][1]

+f[l

en][

j][0

][0]

),其中le

n len

表示n的位數。

在轉移的時候注意

l l

不能超過

r' role="presentation">rr,

r r

不能超過

n' role="presentation">n

n即可。

要計算所有數對中二進位制中1的個數也可以用類似的方式。

最後,∑nl

=1∑n

r=lf

(l,r

)=n∗

∑二進位制

中1的個

數−t ∑l=

1n∑r

=lnf

(l,r

)=n∗

∑二進位制

中1的個

數−

t時間複雜度:o(

t∗lo

g2n)

o (t

∗log

2n

)

#include#include#include#define ll long long

#define tt 1000000007

#define maxn 66

using namespace std;

inline char nc()

inline ll _read()

int t,a[maxn];

ll n,nn,f[maxn][maxn][2][2],g[maxn][maxn][2];//f[i][j][1/0][1/0]:前i位,最長公共字首中有j個1,l是否等於r,r是否等於n的方案數

//g[i][j][1/0]:前i位,有j個1,是否等於n的方案數

int main()else

for(int i=0;ifor(int j=0;j<=i;j++)

if(a[i+1]==1)else

ll ans=0,sum=0;

//for(int j=1;j<=len;j++)printf("%d %d %d %d\n",f[len][j][0][0],f[len][j][0][1],f[len][j][1][0],f[len][j][1][1]);

for(int i=1;i<=len;i++)(ans+=(f[len][i][0][1]+f[len][i][0][0])%tt

*i%tt)%=tt;

for(int i=1;i<=len;i++)(sum+=(g[len][i][0]+g[len][i][1])*i

%tt)%=tt;

printf("%lld\n",((sum*(n%tt)%tt-ans*2

%tt)%tt+tt)%tt);

}return

0;}

dp 樹狀陣列

給定乙個長度為 n n 的序列 a a 求 a a 有多少個長度為 m m 的嚴格遞增子串行。輸入格式 第一行包含整數 t t t,表示共有 t t 組測試資料。每組資料,第一行包含兩個整數 n n 和 m m。第二行包含 n n 個整數,表示完整的序列 a a。輸出格式 每組資料輸出乙個結果,每個...

數字串 (樹狀陣列)

原題 wannafly挑戰賽15 d 題意 給乙個數字串,每次操作改變乙個位置的數字,求每次操作後,有多少個子串滿足以下要求 長度在區間 l,r 內 首數字 尾數字 解析 對於乙個位置p,求的是乙個sum p r 1到p l 1範圍內數字大於p位置的個數和p l 1到p r 1範圍內數字小於p位置的...

hdu 2227 樹狀陣列 dp

題意是求乙個數列的不遞減的子串行的個數 很顯然,如果只用dp來做的話時間是o n n 因為dp i 為前i個數可能的方案,則狀態轉移方程為dp i sum dp j j 先對num按數來進行排序,這道題因為資料較大 用到了離散化 因為更新是是按原序更新的,及i之前的num j 一定比num i 小,...