P1762 偶数
题目描述
给定一个正整数n,请输出杨辉三角形前n行的偶数个数对1000003取模后的结果。
输入格式
一个数
输出格式
结果
输入输出样例
输入 #1 复制
6
输出 #1 复制
6
说明/提示
对于30%的数据,n<=4000
对于70%的数据,n<=4*10^9
对于100%的数据,n<=10^15
杨辉三角形的前七行:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
通过观察,可以发现,奇数个数比偶数个数更有规律,其规律在于:
1.每行奇数个数一定为2^k(k为自然数)
2.当行数恰为2k(k为自然数)时,奇数个数为2k,偶数个数为零
3.当行数恰为2k(k为自然数)时,奇数个数和恰为3(k-1)
4.更巧妙的是:这个规律能更加扩展到一个不为2k的数上,因为每一个数,都能分解为若干项2k的和的形式。
举个例子吧:当n=2333;
2333 = 2048+256+16+8+4+1
通过暴力程序,我们可以找出2333的所有奇数个数为190985
那么,我们找出如下数字
我们可以发现:
行数 所有奇数个数
2048 177147
256 6561
16 81
8 27
4 9
1 1
177147×1 + 6561×2 + 81×4 + 27×8 + 9×16 + 1×32 恰好等于 190985!
Code:
#include<iostream>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
#define mod 1000003
ll a[100],b[100];
int main()
{
ll n,sum=0,num=0,l=1;
scanf("%lld",&n);
b[0]=1;
for(int i=1; i<100; i++)
{
b[i]=b[i-1]*3%mod;
}
num=(n%mod)*(n%mod+1)/2%mod;
int i=0;
while(n)
{
if(n&1)
a[i]=1;
n>>=1;
i++;
}//二进制化
for(int i = 61; i >= 0; i--)
{
if(a[i])
{
num = (num - b[i] * l % mod + mod) % mod;
l = (l % mod * 2) % mod;
}
}
if(num>=sum)
printf("%lld\n",num-sum);
else
printf("%lld\n",mod+num-sum);
return 0;
}