2013长沙网络赛H题Hypersphere (蛋疼的题目 神似邀请赛A题)

Hypersphere Time Limit: 1 Second       Memory Limit: 32768 KB

In the world of k-dimension, there's a large hypersphere made by mysterious metal. People in the world of k-dimension are performing a ceremony to worship the goddess of dimension. They are melting the large hypersphere into metal flow, and then they will cast the metal flow into unit hyperspheres. An unit hypersphere is a hypersphere which radius is 1.

The mysterious metal in k-dimension world has a miraculous property: if k unit hyperspheres made by the mysterious metal are constructed, all of these k unit hyperspheres will be sacrificed to goddess of dimension and disappear from the k-dimension world immediately.

After the ceremony, there will be some unit hyperspheres and a little metal flow left, and people in the world of k-dimension want to know the number of unit hyperspheres left.

You might want to know that how the large hypersphere was constructed. At first, people in the world created a long ruler which length is l. And then, they drew a rectangle with lengthl - 1 and width l. Using some mysterious method, they changed the rectangle into a square but didn't change the area. After that, they extended the ruler's length by the length of the square's side. After successfully made the ruler, people started using magic to construct the large hypersphere. The magic could make a hypersphere become more and more larger. Started with a hypersphere of zero radius, the magic will be continuously used until the radius reached the ruler's length.

Input

There will be several test cases. Each test case contains two integers k (3 ≤ k ≤ 1000000000) and l (2 ≤ l ≤ 1000000000), which are the same meanings as in the description part.

Output

For each test case, please output the number of unit hyperspheres people will get in one line.

Sample Input

3 3
5 6

Sample Output

2
1

题目大意:意思说的真的很蛋疼,听说跟长沙邀请赛的A题特别像,就看了下。努力让自己淡定下来把题目看完。当时比赛的时候跟吉吉都在忙那个HSL颜色转换的那个模拟题,这个题目根本没注意。当时如果看到这个题目,在读懂的基础上可以直接秒掉。。。题目意思说在一个星球,长度为l,每次进行一次就会变成(l+sqrt(l*(l-1))),每次都会增加,不过小数到最后要舍去,题目中说了单位是1才能算。然后没K个单位会被哪个上帝弄消失。看数据意思就是求[l+sqrt(l*(l-1))]^k%k。

 解体思路:直接跟长沙邀请赛的题目一样的,而且貌似还变简单了。那个是向上取整,这个是向下取整。。。大同小异。可以参见2013长沙邀请赛A题http://blog.csdn.net/coraline_m/article/details/9977405
 
2013长沙网络赛H题Hypersphere (蛋疼的题目 神似邀请赛A题)_第1张图片
AC代码:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
long long l,mo;
long long tmp[2][2],p[2][2],ret[2][2];

void init()
{
    ret[0][0]=2*l,ret[0][1]=-l,ret[1][0]=1,ret[1][1]=0;
    p[0][0]=2*l,p[0][1]=-l,p[1][0]=1,p[1][1]=0;
}

void cal1()  //矩阵的平方
{
    int i,j,k;
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
        {
            tmp[i][j]=p[i][j];
            p[i][j]=0;
        }
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            for(k=0;k<2;k++)
               p[i][j]=(p[i][j]+tmp[i][k]*tmp[k][j])%mo;
}

void cal2()  //矩阵的乘法
{
    int i,j,k;
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
        {
            tmp[i][j]=ret[i][j];
            ret[i][j]=0;
        }
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            for(k=0;k<2;k++)
               ret[i][j]=(ret[i][j]+tmp[i][k]*p[k][j])%mo;
}

int main()
{
    long long t;
    while(~scanf("%lld%lld",&mo,&l))
    {
        init();
        t=mo-1;
        while(t)
        {
            if(t&1) cal2();
            cal1();
            t>>=1;
        }
        printf("%lld\n",((ret[1][0]*2*l+ret[1][1]*2)%mo-1+mo)%mo);
    }
}




你可能感兴趣的:(2013网络赛)