HDU 4588 Count The Carries (2013年南京邀请赛)

题目地址:HDU 4588

这题是学长跟我说的一道数位DP。。然后我就按着数位DP去做的,倒是写出来了,但是一直TLE。。后来用类似找规律的方法解出来了。。

首先这题其实就是求每位上总共有多少个1,然后不断从低位开始向高位进位。

方法是比如二进制为1010010的这个数,就可以拆成1000000+10000+10三个数,然后从0到111111就是0和1的一个全排序,那么每一位上的1的个数总和一定是占一半,然后首位+1,那么10000也可以这样算,然后累加起来就好了。但是还要注意的是,首位的1不只是1000000的时候+1,还有后面的也要加上,所以直接从低位开始枚举,并设置一个变量不断累加就行了。

代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
const int mod=100000000;
const int INF=0x3f3f3f3f;
const double eqs=1e-8;
int c[40], d[3][40], sum[103];
LL Cal(LL x, int f)
{
        int i, cnt=0, j;
        LL ans=0;
        while(x){
                c[cnt++]=(x&1);
                x>>=1;
        }
        for(i=0;i<cnt;i++){
                if(c[i]){
                        d[f][i]+=ans+1;
                        for(j=0;j<i;j++){
                                d[f][j]+=(1<<i-1);
                        }
                        ans+=(1<<i);
                }
        }
}
int main()
{
        LL a, b, i, ans;
        while(scanf("%I64d%I64d",&a,&b)!=EOF){
                memset(sum,0,sizeof(sum));
                memset(d,0,sizeof(d));
                Cal(b, 0);
                if(a)
                Cal(a-1, 1);
                ans=0;
                for(i=0;i<35;i++){
                        sum[i]=d[0][i]-d[1][i];
                        //printf("%I64d\n",sum[i]);
                }
                sum[0]>>=1;
                ans=sum[0];
                //printf("%I64d\n",ans);
                for(i=1;i<=100;i++){
                        sum[i]+=sum[i-1];
                        sum[i]>>=1;
                        ans+=sum[i];
                        //printf("%I64d\n",ans);
                }
                printf("%I64d\n",ans);
        }
        return 0;
}
时间: 2024-12-27 09:26:01

HDU 4588 Count The Carries (2013年南京邀请赛)的相关文章

HDU 4588 Count The Carries 数位DP || 打表找规律

2013年南京邀请赛的铜牌题...做的很是伤心,另外有两个不太好想到的地方....a 可以等于零,另外a到b的累加和比较大,大约在2^70左右. 首先说一下解题思路. 首先统计出每一位的1的个数,然后统一进位. 设最低位为1,次低位为2,依次类推,ans[]表示这一位上有多少个1,那么有 sum += ans[i]/2,ans[i+1] += ans[i]/2; sum即为答案. 好了,现在问题转化成怎么求ans[]了. 打表查规律比较神奇,上图不说话. 打表的代码 #include <algo

HDU 4588 Count The Carries(找规律,模拟)

题目 大意: 求二进制的a加到b的进位数. 思路: 列出前几个2进制,找规律模拟. #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <stack> #include <vector> using namespace std; int main() { int

HDU 4588 Count The Carries(数学 二进制 找规律啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4588 Problem Description One day, Implus gets interested in binary addition and binary carry. He will transfer all decimal digits to binary digits to make the addition. Not as clever as Gauss, to make th

Hdu 4588 Count The Carries (规律)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4588 思路: 0     0000 1     0001 2     0010 3     0011 4     0100 5     0101 6     0110 7     0111 8    1000 9    1001 10  1010 观察可知,第i位有(1<<i)个0,与(1<<i)个1,按照长度为(1<<(i+1))长度循环.则对于数n,可以求出1到n中各位

HDU 4588 Count The Carries (数学,计数)

题意:给定两个十进制数,求二进制中,从x加到y的二进制进了多少位. 析:把这些数字的二进制纵向罗列出来,然后一位一位的把和加起来,最终得到总的进位数.从1到x,第i位上1的总数是x左移i+1位再右移i位后得到的, (在第 0位上,1和0以1010101010的周期出现,并且每个周期一个1,在第1位上,1和0以11001100的周期出现,并且每个周期2个1,以此类推,则第n位上的1的个数是x/2^n*2^(n-1),即先左移n+1位,再右移n位),如果x在i位上面上是1,特殊判断一下,求一下周期以

【构造共轭函数+矩阵快速幂】HDU 4565 So Easy! (2013 长沙赛区邀请赛)

链接 :click here~~ 题意: A sequence Sn is defined as: Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn. You, a top coder, say: So easy! [解题思路] 给一张神图,推理写的灰常明白了,关键是构造共轭函数,这一点实在是要有数学知识的理论基础,推出了递推式,接下

2013 南京邀请赛 C count the carries

1 /** 2 大意: 给定区间(a,b), 将其转化为二进制 计算从a+(a+1)+(a+2)....+(a+b-1),一共有多少次进位 3 思路: 将(a,b)区间内的数,转化为二进制后,看其每一位一共有多少个1 4 可知最低位循环为2,第二位循环为4 5 ---〉 所以每一位的1的个数为 : 假设为第三位 (n-n%8)/8*8/2===>(n-n%8)/2 6 ------> 如果n%8 大于8/2 那么应该再加上 n%8-8/2 7 **/ 8 #include <iostre

hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有的连通分量只有一个点,当舍去该点时候,连通分量-1: 复习求割点的好题! #include<iostream> #include<cstdio> #include<vector> using namespace std; int n,m; vector<vector&

2013 ACM-ICPC南京赛区全国邀请赛

题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2013 ACM-ICPC南京赛区全国邀请赛--题目重现&source=1&searchmode=source A(HDU4586) Play the Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1