3329 Xorequ 數字DP 矩陣乘法

2021-07-10 09:02:54 字數 1531 閱讀 9010

數字dp好虛啊。。最近練練。

首先我們要對題意進行合理的轉化: xx

or3x

=2x 就等價於xx

or2x

=3x ,且我們知道x+

2x=3

x ,即

x 與

x<<

1在相加時不能有進製,所以有xa

nd(x

<<1)

=0,那麼就轉化為區間內滿足這個條件的數量。 用f

i 表示二進位制表示下有

i 位,且最高位為

0的個數,用gi

表示二進位制表示下有

i 位,且最高位為

1的個數。

那麼轉移顯然:fi

=fi−

1+gi

−1,g

i=fi

−1先看第二問,第二問其實就是要求fn

,因為fn

表示的是[0

,2n)

的答案個數,而

0 不是正整數,2n

是合法答案,所以總共還是有fn

個,打表可以發現fn

是fib

onac

ci數列的第n+

2 項,可以直接矩陣乘法求。

再看第一問,這是乙個數字dp。 加入n

=22,將n+

1 表示成二進位制

10111

,並將答案劃分成幾段: [0

,01111

] ,答案為f4

。 [10000

,10011

] ,答案為f2

。 [10100

,10101

] ,答案為f1

。 [10110

,10111

] ,由於有相鄰的

1 存在,後面的答案都一定不合法,計算結束。

最後要減

1,因為

0 是不合法的。

數字dp一直很弱,一是邊界問題,二是計數問題,還要多加練習啊。

#include

#include

#include

#define ll long long

#define mod 1000000007

using

namespace

std;

ll f[70],g[70];

struct matrix

friend matrix operator*(matrix a,matrix b)

friend matrix operator^(matrix a,ll b)

};inline ll read()

while (c>='0'&&c<='9')

return a*f;

}inline ll query_1(ll x)

else flag=0;

return ans-1;

}inline ll query_2(ll x)

int main()

return

0;}

BZOJ 1833 count 數字計數 數字DP

description 給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。input 輸入檔案中僅包含一行兩個整數a b,含義如上所述。output 輸出檔案中包含一行10個整數,分別表示0 9在 a,b 中出現了多少次。解題報告 這道題很容易看出是乙個數字d...

ARC075F Mirrored 搜尋 數字dp

給定正整數dd,求有多少個正整數nn,滿足rev n n drev n n d,其中rev n rev n 表示將nn的十進位制表示翻轉來讀得到的數 乙個正整數dd 滿足上述條件的正整數的個數 case 1 63case 2 75case 3 864197532case 1 2case 2 0cas...

Codeforces 1073E 狀壓 數字dp

題意 輸入l r k,輸出區間 l,r 內數字種數不超過k的數字之和,比如l 10,r 50,k 1,答案就是11 22 33 44 110 1 l 1e18,1 e 1e18,1 k 9 思路比較明顯的數字dp,因為要考慮當前所用的數字種類所以要把用過的數字狀壓一下,用dp i s 表示從低到高遞...