HDU 4588 Count The Carries(数学 找规律)
2013-09-04 21:18
337 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4588
这个题目规律还是好找的,具体实现好好想想也不难,但是要注意,进位可能会到60位,要注意,尽量让数组下标在不越界的情况下取最大
题目意思很简单,看题目给的例子就看出来了,给定a b : a<b 求二进制a a+1 a+2 .....b求和的过程中其二进制的进位次数,开始想暴力下,
后来一看范围还是算了,老老实实找规律吧,其实这个题目找的就是ab区间内所有数组二进制每一位的1出现的次数,然后我们可以发现这样
一个规律第一位循环2,第二位循环为4
也就是
00000
00001
00010
00011
00100
00101
00110
00111
竖着看,发现规律了吧!
最后求解答案的时候不用分开求,直接求b--0的和a-1--0的,然后直接相减就OK 了!
#include <iostream>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#define LL __int64
using namespace std;
#define maxn 200
LL num[maxn],a,b,num_a,num_b,num_c,ans,mod;
LL my_pow(LL a,LL b){
LL ans=a;
b--;
while(b--){
ans*=a;
}
return ans;
}
int init(){
for(int i=0;i<61;i++)
num[i]=my_pow(2,i+1);
return 0;
}
int main(){
int i,j,k;
init();
while(scanf("%I64d%I64d",&a,&b)!=EOF){
ans=num_c=0;
a--;
if(a<=0) a=0;
for(i=0;i<60;i++){
mod=(a+1)%num[i];
num_a=((a+1)/num[i])*(num[i]/2)+(mod > (num[i]/2) ? (mod-num[i]/2) : 0);
mod=(b+1)%num[i];
num_b=((b+1)/num[i])*(num[i]/2)+(mod > (num[i]/2) ? (mod-num[i]/2) : 0);
num_b=num_c+num_b-num_a;
num_c=num_b/2;
ans+=num_c;
}
printf("%I64d\n",ans);
}
return 0;
}
这个题目规律还是好找的,具体实现好好想想也不难,但是要注意,进位可能会到60位,要注意,尽量让数组下标在不越界的情况下取最大
题目意思很简单,看题目给的例子就看出来了,给定a b : a<b 求二进制a a+1 a+2 .....b求和的过程中其二进制的进位次数,开始想暴力下,
后来一看范围还是算了,老老实实找规律吧,其实这个题目找的就是ab区间内所有数组二进制每一位的1出现的次数,然后我们可以发现这样
一个规律第一位循环2,第二位循环为4
也就是
00000
00001
00010
00011
00100
00101
00110
00111
竖着看,发现规律了吧!
最后求解答案的时候不用分开求,直接求b--0的和a-1--0的,然后直接相减就OK 了!
#include <iostream>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#define LL __int64
using namespace std;
#define maxn 200
LL num[maxn],a,b,num_a,num_b,num_c,ans,mod;
LL my_pow(LL a,LL b){
LL ans=a;
b--;
while(b--){
ans*=a;
}
return ans;
}
int init(){
for(int i=0;i<61;i++)
num[i]=my_pow(2,i+1);
return 0;
}
int main(){
int i,j,k;
init();
while(scanf("%I64d%I64d",&a,&b)!=EOF){
ans=num_c=0;
a--;
if(a<=0) a=0;
for(i=0;i<60;i++){
mod=(a+1)%num[i];
num_a=((a+1)/num[i])*(num[i]/2)+(mod > (num[i]/2) ? (mod-num[i]/2) : 0);
mod=(b+1)%num[i];
num_b=((b+1)/num[i])*(num[i]/2)+(mod > (num[i]/2) ? (mod-num[i]/2) : 0);
num_b=num_c+num_b-num_a;
num_c=num_b/2;
ans+=num_c;
}
printf("%I64d\n",ans);
}
return 0;
}
相关文章推荐
- HDU 4588 Count The Carries(数学 二进制 找规律啊)
- [HDOJ4588]Count The Carries(数学,规律)
- 数学题-hdu-4588-Count The Carries
- Hdu 4588 Count The Carries (规律)
- hdu 4588 Count The Carries 数学
- HDU 4588 Count The Carries (数学-- 二进制技巧枚举)
- HDU 4588 Count The Carries 数学
- HDU 4588 Count The Carries 数位DP || 打表找规律
- HDU 4588 Count The Carries(数学)
- HDU 4588 Count The Carries 数位DP || 打表找规律
- HDU 4588 Count The Carries(数学统计)
- HDU 4588 Count The Carries(规律)
- HDU 4588 Count The Carries(找规律,模拟)
- HDU 4588 Count The Carries (数学,计数)
- HDU-4588 Count The Carries (模拟)
- 【瞎搞】 HDU 4588 Count The Carries
- hdu 4588 Count The Carries
- HDU 4588 Count The Carries (2013年南京邀请赛)
- hdu 4588 Count The Carries 南京邀请赛
- Hdu 4588 Count The Carries(数位统计)