[HDOJ4588]Count The Carries(数学,规律)
生活随笔
收集整理的這篇文章主要介紹了
[HDOJ4588]Count The Carries(数学,规律)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4588
題意:從a加到b,每次結果加到a上,看在二進制下一共發生了多少次進位。
把0到n的所有數二進制下下來,可以發現規律:第一位循環節為2,每次循環01。第二位循環節是4,每次循環0011。以此類推。
計算兩個數的各位分別出現了多少次1,再減掉。模擬進位統計進位次數就可以。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int maxn = 10100; 6 LL a, b; 7 LL vis1[maxn], vis2[maxn]; 8 LL vis[maxn]; 9 10 void f(LL* vis, LL x) { 11 memset(vis, 0, sizeof(vis)); 12 for(LL i = 1; i <= 62; i++) { 13 LL t = (1LL << i); 14 LL div = x / t; 15 LL rem = x % t; 16 LL cnt = div * (1LL << (i - 1LL)); 17 cnt += (rem + 1LL) > (t / 2LL) ? rem + 1 - t / 2LL : 0LL; 18 vis[i] = cnt; 19 } 20 } 21 22 int main() { 23 // freopen("in", "r", stdin); 24 // freopen("out.txt", "w", stdout); 25 while(~scanf("%lld%lld",&a,&b)) { 26 f(vis1, a-1); f(vis2, b); 27 memset(vis, 0, sizeof(vis)); 28 for(LL i = 1; i <= 62; i++) { 29 vis[i] = vis2[i] - vis1[i]; 30 } 31 LL ret = 0; 32 for(LL i = 1; i <= 63; i++) { 33 ret += vis[i] / 2LL; 34 vis[i+1] += vis[i] / 2LL; 35 } 36 printf("%lld\n", ret); 37 } 38 return 0; 39 }?
轉載于:https://www.cnblogs.com/kirai/p/6792441.html
總結
以上是生活随笔為你收集整理的[HDOJ4588]Count The Carries(数学,规律)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: maven工程搭建
- 下一篇: 找出一个文件夹下后缀名为.jpg的文件