日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Xorequ(BZOJ3329+数位DP+斐波那契数列)

發布時間:2025/4/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Xorequ(BZOJ3329+数位DP+斐波那契数列) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

傳送門

思路

\(a\bigoplus b=c\rightarrow a=c\bigoplus b\)得原式可化為\(x\bigoplus 2x=3x\)

又異或是不進位加法,且\(2x=1<<x,3x=(1<<x)+x\),因此可知\((x\&2x)=0\),也就是說\(x\)的二進制中沒有相鄰的\(1\)

第一問就可以用數位\(DP\)來寫。

對于第二問我們可以考慮遞推式,我們定義\(f(x)\)表示\(2^x\)時滿足等式的數的個數,則

  • 如果第\(n\)位是\(1\),那么第\(n-1\)位就必須是\(0\),此時就相當于忽略第\(n,n-1\)位,轉變成最高位是\(n-2\)的個數,因此\(f(n)\)可以從第\(n-2\)位轉移過來;
  • 如果第\(n\)位是\(0\),那么就相當于忽略第\(n\)位,轉變成最高位是\(n-1\)的個數,因此\(f(n)\)可以從第\(n-1\)位轉移過來。

最后得到遞推式\(f(n)=f(n-1)+f(n-2)\),也就是斐波那契數列,注意該遞推式中的\(n\)是指\(2\)進制中最高位是多少,也就是題目中的\(n-1\),因次本題答案是\(f(n+1)\)

其實這兩個規律可以通過打表找出來的~

代碼

#include <set> #include <map> #include <deque> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <bitset> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std;typedef long long LL; typedef pair<LL, LL> pLL; typedef pair<LL, int> pLi; typedef pair<int, LL> pil;; typedef pair<int, int> pii; typedef unsigned long long uLL;#define lson rt<<1 #define rson rt<<1|1 #define lowbit(x) x&(-x) #define name2str(name) (#name) #define bug printf("*********\n") #define debug(x) cout<<#x"=["<<x<<"]" <<endl #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin) #define IO ios::sync_with_stdio(false),cin.tie(0)const double eps = 1e-8; const int mod = 1000000007; const int maxn = 50000 + 7; const double pi = acos(-1); const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3fLL;int t; LL n; int a[62]; int f[3], base[3][3]; LL dp[62][2][2][2];LL dfs(int pos, int pre, int flag, bool limits, bool lead) {if(pos == -1) return flag && (!lead);if(!limits && dp[pos][pre][flag][lead] != -1) return dp[pos][pre][flag][lead];int up = limits ? a[pos] : 1;LL ans = 0;for(int i = 0; i <= up; ++i) {if(i == 0) ans += dfs(pos - 1, 0, flag, limits && i == a[pos], lead);else ans += dfs(pos - 1, 1, flag && (pre != 1), limits && a[pos] == i, 0);}if(!limits) dp[pos][pre][flag][lead] = ans;return ans; }LL solve(LL x) {int len = 0;while(x) {a[len++] = x % 2;x >>= 1;}return dfs(len - 1, 0, 1, 1, 1); }void mul() {int c[3];memset(c, 0, sizeof(c));for(int i = 0; i < 2; ++i) {for(int j = 0; j < 2; ++j) {c[i] = (c[i] + 1LL * f[j] * base[j][i] % mod) % mod;}}memcpy(f, c, sizeof(c)); }void mulself() {int c[3][3];memset(c, 0, sizeof(c));for(int i = 0; i < 2; ++i) {for(int j = 0; j < 2; ++j) {for(int k = 0; k < 2; ++k) {c[i][j] = (c[i][j] + 1LL * base[i][k] * base[k][j] % mod) % mod;}}}memcpy(base, c, sizeof(c)); }int main() { #ifndef ONLINE_JUDGEFIN; #endifmemset(dp, -1, sizeof(dp));scanf("%d", &t);while(t--) {scanf("%lld", &n);printf("%lld\n", solve(n));base[0][0] = 1, base[0][1] = 1;base[1][0] = 1, base[1][1] = 0;f[0] = f[1] = 1;while(n) {if(n & 1) mul();mulself();n >>= 1;}printf("%d\n", f[0]);}return 0; }

轉載于:https://www.cnblogs.com/Dillonh/p/11327901.html

總結

以上是生活随笔為你收集整理的Xorequ(BZOJ3329+数位DP+斐波那契数列)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。