HDU4028The time of a day

HDU4028The time of a day

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)

Total Submission(s): 143    Accepted Submission(s): 35

Problem Description

There are no days and nights on byte island, so the residents here can hardly determine the length of a single day. Fortunately, they have invented a clock with several pointers. They have N pointers which can move round the clock. Every pointer ticks once per second, and the i-th pointer move to the starting position after i times of ticks. The wise of the byte island decide to define a day as the time interval between the initial time and the first time when all the pointers moves to the position exactly the same as the initial time.

The wise of the island decide to choose some of the N pointers to make the length of the day greater or equal to M. They want to know how many different ways there are to make it possible.

 

Input

There are a lot of test cases. The first line of input contains exactly one integer, indicating the number of test cases.

  For each test cases, there are only one line contains two integers N and M, indicating the number of pointers and the lower bound for seconds of a day M. (1 <= N <= 40, 1 <= M <= 263-1)

 

Output

For each test case, output a single integer denoting the number of ways.

 

Sample Input

3

5 5

10 1

10 128

 

Sample Output

Case #1: 22

Case #2: 1023

Case #3: 586

 

Source

The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest

 *********************************************************************************************

这是2011年上海赛区网络赛的第8道,下午比赛的时候碍于庞大的数据量,不知道该怎么处理。后来看了大牛的解题报告才知道有一种dp叫做离散dp,就是dp的某一维,当这一维的数字不是连续的,有大量空缺的时候,就可以用离散dp,用离散化使得dp的一维下标变小。

对于这道题目,dp第一维i是前几个,第二维表示取到前i个的时候lcm的值,这个lcm的值是可以离散的,最多只有3W个多,差距就在这里,这个地方不会离散就不会做了。

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;

typedef long long  LL;
map<LL,LL>dp[45];

LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a*b/gcd(a,b);}

int main()
{
    dp[0][1]=1;
    for(LL i=1;i<=40;i++)
    {
        dp[i]=dp[i-1];
        for(map<LL,LL>::iterator it=dp[i-1].begin();it!=dp[i-1].end();it++)
            dp[i][lcm(it->first,i)]+=it->second;
    }
    LL ncase;
    cin>>ncase;
    for(LL h=1;h<=ncase;h++)
    {
        LL n,m;
        cin>>n>>m;
        cout<<"Case #"<<h<<": ";
        if(m==1)
            cout<<((1<<n)-1)<<endl;
        else
        {
            LL sum=0;
            for(map<LL,LL>::iterator it=dp[n].begin();it!=dp[n].end();it++)
                if(it->first>=m)
                    sum+=it->second;
            cout<<sum<<endl;
        }
    }
}

  

posted on 2011-09-10 21:18  Fatedayt  阅读(1004)  评论(0编辑  收藏  举报

导航