hdu 4588 Count The Carries
生活随笔
收集整理的這篇文章主要介紹了
hdu 4588 Count The Carries
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
思路:容易發現二進制表示的數的最低位規律是01010101……;接著是001100110011……;接著是:0000111100001111……
這樣我們發現每一位的循環節是2^(i+1),前2^i是0,后面的是1.這樣就可以算出每一位1出現的次數。
代碼如下:
?
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define ll __int64 6 using namespace std; 7 ll a[35]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384, 8 32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608, 9 16777216,33554432,67108864,134217728,268435456,536870912,1073741824, 10 2147483648,4294967296,8589934592,17179869184}; 11 ll sa[35],sb[35],s[100]; 12 int get(int n) 13 { 14 int bit=0; 15 while(n){ 16 bit++; 17 n>>=1; 18 } 19 return bit; 20 } 21 void solve(int n,ll *aa) 22 { 23 ll i,j,nn=n+1; 24 if(n<=0) return; 25 int len=get(n); 26 for(int k=0;k<len;k++){ 27 aa[k]+=nn/a[k+1]*a[k]; 28 j=nn%a[k+1]; 29 if(j>=a[k]) j-=a[k]; 30 else j=0; 31 aa[k]+=j; 32 } 33 } 34 int main() 35 { 36 int n,m,len1,len2; 37 ll c; 38 while(scanf("%d%d",&n,&m)!=EOF){ 39 memset(sa,0,sizeof(sa)); 40 memset(sb,0,sizeof(sb)); 41 memset(s,0,sizeof(s)); 42 solve(m,sa); 43 solve(n-1,sb); 44 for(int i=0;i<35;i++) s[i]=sa[i]-sb[i]; 45 ll ans=0; 46 for(int i=0;i<100;i++){ 47 c=(s[i]>>1); 48 ans+=c; 49 s[i+1]+=c; 50 } 51 printf("%I64d\n",ans); 52 } 53 return 0; 54 } View Code?
?
?
轉載于:https://www.cnblogs.com/xin-hua/p/3269914.html
總結
以上是生活随笔為你收集整理的hdu 4588 Count The Carries的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wzplayer for android
- 下一篇: 使IE6下PNG背景图片透明的七种方法