hdu 3524 Perfect Squares
A number x is called a perfect square if there exists an integer b
satisfying x=b^2. There are many beautiful theorems about perfect squares in mathematics. Among which, Pythagoras Theorem is the most famous. It says that if the length of three sides of a right triangle is a, b and c respectively(a < b <c), then a^2 + b^2=c^2.
In this problem, we also propose an interesting question about perfect squares. For a given n, we want you to calculate the number of different perfect squares mod 2^n. We call such number f(n) for brevity. For example, when n=2, the sequence of {i^2 mod 2^n} is 0, 1, 0, 1, 0……, so f(2)=2. Since f(n) may be quite large, you only need to output f(n) mod 10007.
Input
The first line contains a number T<=200, which indicates the number of test case.
Then it follows T lines, each line is a positive number n(0
题意:
任何数模上2^n都会有循环节,给你n问你循环节里有多少个不同的数字。
分析:
通过打表可以发现规律(其实我是看了题解才发现的。。。。)
打表找规律的题如果相邻项发现不了什么规律的话,就再看看奇数项和偶数项是否有规律
而这道题目就是这样
打表发现前15项为
2,2,3,4,7,12,23,44,87,172,343,684,1367,2732,5463 2 , 2 , 3 , 4 , 7 , 12 , 23 , 44 , 87 , 172 , 343 , 684 , 1367 , 2732 , 5463
奇数项: 2,3,7,23,87,343,1367,5463 2 , 3 , 7 , 23 , 87 , 343 , 1367 , 5463
偶数项: 2,4,12,44,172,684,2732 2 , 4 , 12 , 44 , 172 , 684 , 2732
奇数项分别相差 1(20),4(22),16(24),64(26),256(28),1024(210) 1 ( 2 0 ) , 4 ( 2 2 ) , 16 ( 2 4 ) , 64 ( 2 6 ) , 256 ( 2 8 ) , 1024 ( 2 10 )
偶数项相差 2(21),8(23),32(25),128(27),512(29),2048(211) 2 ( 2 1 ) , 8 ( 2 3 ) , 32 ( 2 5 ) , 128 ( 2 7 ) , 512 ( 2 9 ) , 2048 ( 2 11 )
因此根据上面的规律比较容易得到递推式
奇数项: f[i]=f[i−1]+22i−4 f [ i ] = f [ i − 1 ] + 2 2 i − 4 (其中i代表第i个奇数项 i=n2+1 i = n 2 + 1 )
偶数项: f[i]=f[i−1]+22i−3 f [ i ] = f [ i − 1 ] + 2 2 i − 3 (其中i代表第i个偶数项 i=n2 i = n 2 )
根据递推式可以得到通项
下面具体说一下怎么得到通项公式
大家应该还记得高中数学中根据递推式求通项的一个方法:
累加法
1)首先我们求奇数项的通项:
我们将每一项都写出来得到
2=2+0
2
=
2
+
0
3=2+22×2−4
3
=
2
+
2
2
×
2
−
4
7=3+22×3−4
7
=
3
+
2
2
×
3
−
4
.
.
.
f[i]=f[i−1]+22i−4
f
[
i
]
=
f
[
i
−
1
]
+
2
2
i
−
4
我们将所有式子累加起来,得到一个新的等式发现可以消去大部分项
最终剩下的就是
f[i]=2+22×2−4+22×3−4+...+22i−4 f [ i ] = 2 + 2 2 × 2 − 4 + 2 2 × 3 − 4 + . . . + 2 2 i − 4
后面是等比数列故:
奇数项的通项为:
f[i]=2+1×(4i−1−1)4−1=22i−2+53 f [ i ] = 2 + 1 × ( 4 i − 1 − 1 ) 4 − 1 = 2 2 i − 2 + 5 3
(其中 i=n2+1 i = n 2 + 1 )
2)我们再来求偶数项的同项:
同样的套路把式子全写出来得到
2=2+0
2
=
2
+
0
4=2+22×2−3
4
=
2
+
2
2
×
2
−
3
12=4+22×3−3
12
=
4
+
2
2
×
3
−
3
.
.
.
f[i]=f[i−1]+22i−3
f
[
i
]
=
f
[
i
−
1
]
+
2
2
i
−
3
将各个等式相加同样发现可以消去大部分常数项项最终得到
f[i]=2+2×(4i−1−1)4−1=22i−1+43 f [ i ] = 2 + 2 × ( 4 i − 1 − 1 ) 4 − 1 = 2 2 i − 1 + 4 3
偶数项通项:
f[i]=22i−1+43 f [ i ] = 2 2 i − 1 + 4 3
其中 i=n2 i = n 2
综上所述:
奇数项通项:
f[i]=2+1×(4i−1−1)4−1=22i−2+53 f [ i ] = 2 + 1 × ( 4 i − 1 − 1 ) 4 − 1 = 2 2 i − 2 + 5 3 (其中 i=n2+1 i = n 2 + 1 )
偶数项通项:
f[i]=22i−1+43 f [ i ] = 2 2 i − 1 + 4 3 (其中 i=n2) i = n 2 )
因此只需要判断n的奇偶即可直接套用公式注意求3的逆元
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int mod = 10007;
ll q_pow(ll a,ll b){
ll ans = 1;
while(b){
if(b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
int main(){
int T,cas = 0;
ll n,ans;
ll inv3 = q_pow(3,mod-2);
scanf("%d",&T);
while(T--){
scanf("%lld",&n);
if(n & 1)
ans = (q_pow(2,2 * (n / 2 + 1) - 2) + 5) % mod * inv3 % mod;
else
ans = (q_pow(2,2 * (n / 2) - 1) + 4) % mod * inv3 % mod;
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}