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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2020ICPC(上海) - Sum of Log(数位dp)

發布時間:2024/4/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020ICPC(上海) - Sum of Log(数位dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出?X 和 Y,求?

題目分析:因為涉及到了位運算且看似可以遞推,所以考慮數位dp,因為統計答案時的 i 和 j 的與為 0,所以 i + j = i & j,那么取 log 其實就是最高位,也就是 max( highbit_i , highbit_j )

最簡單的狀態就是:dp[ pos ][ highbit_x ][ highbit_y ][ x <= X ][ y <= Y ],不過很可惜會 TLE

因為我們到達終點后,我們只關心 max( highbit_x , highbit_y ),所以狀態優化為?dp[ pos ][ max( highbit_x , highbit_y ) ][ x <= X ][ y <= Y ],很可惜還是會 TLE

然后就沒思路了,去看了題解恍然大悟,其實我們可以去枚舉最高位的,假設 i 為最高位,也就是?max( highbit_x , highbit_y ) 為 i,此時只有兩種情況:

  • x 和 y 大于 i 的位置全為 0,x 的 i 為 1,y 的 i 為 0
  • x 和 y 大于 i 的位置全為 0,x 的 i 為 0,y 的 i 為 1
  • 每次都去數位 dp 即可,時間復雜度下降到了最終的 O( 2 * 35 * 2 * 2 ) ≈ O( 280 )

    最后再補充一下,dp 數組記憶化的實質上是當前狀態下有多少個 i & j == 0,最后的貢獻還是需要乘上相應的 highbit + 1

    代碼:
    ?

    //#pragma GCC optimize(2) //#pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e3+100;const int mod=1e9+7;LL dp[35][2][2];//dp[pos][i<=x][j<=y]int A[35],B[35];LL dfs(int pos,int f1,int f2) {if(pos==-1)return 1;if(dp[pos][f1][f2]!=-1)return dp[pos][f1][f2];int upa=f1?A[pos]:1;int upb=f2?B[pos]:1;LL ans=0;for(int i=0;i<=upa;i++)//枚舉A for(int j=0;j<=upb;j++)//枚舉Bif((i&j)==0)ans=(ans+dfs(pos-1,f1&&i==upa,f2&&j==upb))%mod;return dp[pos][f1][f2]=ans; }LL solve(int x,int y) {memset(A,0,sizeof(A));memset(B,0,sizeof(B));memset(dp,-1,sizeof(dp));int cnt1=0,cnt2=0;//highbitint xx=x,yy=y;while(xx){A[cnt1++]=xx&1;xx>>=1;}while(yy){B[cnt2++]=yy&1;yy>>=1;}LL ans=0;for(int i=0;i<max(cnt1,cnt2);i++){LL res=0;if(i<cnt1)//第i位x為1,y為0 res+=dfs(i-1,i==cnt1-1,i>=cnt2);if(i<cnt2)//第i為y為1,x為0 res+=dfs(i-1,i>=cnt1,i==cnt2-1);ans=(ans+res*(i+1))%mod;}return ans; }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--){int x,y;scanf("%d%d",&x,&y);printf("%lld\n",solve(x,y));}return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的2020ICPC(上海) - Sum of Log(数位dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

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