2020上海ICPC现场赛 C Sum of Log
https://ac.nowcoder.com/acm/contest/9925/C
今天我們隊(duì)配合問題極大。。。這道前期數(shù)位DP給數(shù)學(xué)隊(duì)友在看他半天不會寫,然后我這個(gè)數(shù)學(xué)辣雞wa了一年D。。。交換一下兩個(gè)題感覺能少2小時(shí)罰時(shí)。。。
這題意思就是 i,j 隨便選,不超過X,Y,然后i,j二進(jìn)制上不能有相同的位都是1,然后一個(gè)數(shù)字的貢獻(xiàn)就是他二進(jìn)制上的最高位的1是哪一位+1就行了
那么就是個(gè)簡單數(shù)位DP,由于貢獻(xiàn)僅與最高位有關(guān),我們dp只要算數(shù)量就行了,然后用全局變量來計(jì)算答案
dp[k][fmx][fx][fy],k表示已經(jīng)到2進(jìn)制的哪一位了,注意k=1-32分別對應(yīng)2^31---2^0位,然后fmx表示已經(jīng)有1了沒有,fx表示i是否還頂著X這個(gè)上邊界,fy表示j是否還頂著Y,的方案數(shù)
那么每枚舉一個(gè)k,我們可以安排i,j這一位都是0,i=1 j=0或者i=0 j=1這樣3種情況,由于我們答案只與最高位有關(guān),那么當(dāng)fmx==1 且當(dāng)前有一位為1的時(shí)候,加入總答案,ans+=tmp*(33-k)
#include<bits/stdc++.h> using namespace std; typedef long long ll;const int mod=1e9+7;ll x,y;ll ans; int xa[35],ya[35]; ll dp[35][2][2][2];inline void prework() {scanf("%lld%lld",&x,&y);for(int i=31;i>=0;i--)xa[31-i+1]=(x>>i)&1;for(int i=31;i>=0;i--)ya[31-i+1]=(y>>i)&1; }inline ll dfs(int k,bool fmx,bool fx,bool fy) {if(k>32)return 1;if(dp[k][fmx][fx][fy]>=0)return dp[k][fmx][fx][fy];ll ret=0,tmp;int upx=(!fx || xa[k]),upy=(!fy || ya[k]);(ret+=dfs(k+1,fmx,fx&&xa[k]==0,fy&&ya[k]==0))%=mod;if(upx>=1){tmp=dfs(k+1,0,fx&&xa[k]==1,fy&&ya[k]==0);ret=(ret+tmp)%mod;if(fmx)(ans+=(33-k)*tmp%mod)%=mod;}if(upy>=1){tmp=dfs(k+1,0,fx&&xa[k]==0,fy&&ya[k]==1);ret=(ret+tmp)%mod;if(fmx)(ans+=(33-k)*tmp%mod)%=mod;}dp[k][fmx][fx][fy]=ret;return ret; }inline void mainwork() {memset(dp,-1,sizeof(dp));ans=0;dfs(1,1,1,1); }inline void print() {printf("%lld\n",ans); }int main() {int t;scanf("%d",&t);while(t--){prework();mainwork();print();}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的2020上海ICPC现场赛 C Sum of Log的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kindle所支持的格式
- 下一篇: es5 js日期格式化