题目连接:人类史上最大最好的希望事件
这题就是个斐波那契的一个变形数列,只不过是把每一个数变成它的平方,再根据题意做就可以了。挺简单的不过要注意的是这些数非常的大,要不断的对题目给出的数进行取余。由于数据很大,所以要进行打表,打表的方式是打出这个数之前的所有数的和,存放在一个数组里,最后求的时候只要做个差就行了,但要注意的是作差时可能为负数,所以加上mod在对mod取余。
Problem Description |
作为CNCS的半壁江山,狗哥常常在宇宙中心邵阳眺望黄浦江,夜晚的星空总是迷人,有时候还能见到彗星滑落。
狗哥是幸运的,他在两秒钟内看到了十七颗彗星划过天际,作为打ACM的学者,自然不会有「稳定-1」情况。他开始研究彗星运动的轨迹,发现他们都遵照斐波那契螺旋线在运动着。
尤里卡!狗哥觉得这就是找寻「生命,宇宙和一切的终极答案」的精要所在,但是怎么表示呢?狗哥觉得求取斐波那契螺旋线经过的一个个方格的面积之和就是公式的表现。
例如下图,螺旋线每划过一个方格,都转过了四分之一圈。如果我们以四分之一圈为单位,那么我们用类似带分数的形式表示螺旋线转动的起点和终点。例如,0+0 到 0 + 1 意即从第一个方格转到第二个方格,划过了前两个方格,他们的面积之和为2(1+1)。同理,0+0 到 1+0 划过了前五个方格,他们的面积之和为40(1+1+4+9+25)。
但是聪明的狗哥需要一个程序去获得指定范围内的螺旋线面积之和,狗哥给了你一首「希望之花」的时间,而他需要利用这个时间去打出四暗刻单骑。如果你能完成这个程序,狗哥会封你为格拉摩根伯爵
Input |
不定组数据。
首先输入一个整数Q,代表狗哥询问次数。
接下来Q行,每行四个整数a,b,c,d,代表狗哥想求 a+b 到 c+d 之间的螺旋线面积之和。
1<= Q <= 10000
0<= a,c <= 10000
0 <= b,d <= 3
结果对192600817取模
Output |
一个数字,表示螺旋线面积之和。
Sample Input |
4
0 0 0 1
0 0 1 0
1 2 2 1
1 1 0 3
4
0 0 0 1
0 0 1 0
1 2 2 1
1 1 0 3
Sample Output |
2
40
4791
98
2
40
4791
98
代码如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll dis[10101][4];
ll vis[1010100];
int main()
{
ll p=2,sum;
ll mod=192600817;
dis[-1][3]=0;
vis[1]=1;vis[2]=1;
for(int i=3;i<=1001000;i++)
{
vis[i]=(vis[i-1]+vis[i-2])%mod;
}
memset(dis,0,sizeof(dis));
for(ll i=0;i<=10010;i++)
{
sum=0;
for(ll j=0;j<=3;j++)
{
if(i==0&&j==0)
{
dis[i][j]=1;
continue;
}
if(i==0&&j==1)
{
dis[i][j]=2;
continue;
}
p=p+1;
sum=(vis[p]*vis[p])%mod;
if(j==0)
dis[i][j]=(dis[i-1][3]+sum)%mod;
else
dis[i][j]=(dis[i][j-1]+sum)%mod;
}
}
ll n;
while(~scanf("%lld",&n))
{
ll a,b,a1,b1;
for(ll i=0;i<n;i++)
{
scanf("%lld%lld%lld%lld",&a,&b,&a1,&b1);
if(a<a1)
{
if(b==0)
printf("%lld\n",(dis[a1][b1]-dis[a-1][3]+mod)%mod);
else
printf("%lld\n",(dis[a1][b1]-dis[a][b-1]+mod)%mod);
}
else if(a==a1)
{
if(b<=b1)
{
if(b==0)
printf("%lld\n",(dis[a1][b1]-dis[a-1][3]+mod)%mod);
else
printf("%lld\n",(dis[a1][b1]-dis[a][b-1]+mod)%mod);
}
else
{
if(b1==0)
printf("%lld\n",(dis[a][b]-dis[a1-1][3]+mod)%mod);
else
printf("%lld\n",(dis[a][b]-dis[a1][b1-1]+mod)%mod);
}
}
else if(a>a1)
{
if(b1==0)
printf("%lld\n",(dis[a][b]-dis[a1-1][3]+mod)%mod);
else
printf("%lld\n",(dis[a][b]-dis[a1][b1-1]+mod)%mod);
}
}
}
return 0;
}