Description
令(1+sqrt(2))n=e(n)+f(n)*sqrt(2),其中e(n),f(n)都是整数,显然有(1-sqrt(2))n=e(n)-f(n)*sqrt(2)。令g(
n)表示f(1),f(2)…f(n)的最小公倍数,给定两个正整数n和p,其中p是质数,并且保证f(1),f(2)…f(n)在模p意义
下均不为0,请计算sigma(i*g(i)),1<=i<=n.其在模p的值。
Input
第一行包含一个正整数 T ,表示有 T 组数据,满足 T≤210 。接下来是测试数据。每组测试数据只占一行,包含 两个正整数 n 和 p
,满足 1≤n≤106,2≤p≤109+7 。保证所有测试数据的 n 之和不超过 3×10^6 。
Output
对于每组测试数据,输出一行一个非负整数,表示这组数据的答案。
Sample Input
5
1 233
2 233
3 233
4 233
5 233
Sample Output
1
5
35
42
121
题解
推一下式子
会有 e ( n + 1 ) = e ( n ) + 2 ∗ f ( n ) e(n+1)=e(n)+2*f(n) e(n+1)=e(n)+2∗f(n), f ( n + 1 ) = e ( n ) + f ( n ) f(n+1)=e(n)+f(n) f(n+1)=e(n)+f(n)
所以 e ( n + 1 ) = f ( n ) + f ( n + 1 ) e(n+1)=f(n)+f(n+1) e(n+1)=f(n)+f(n+1)
所以 f ( n + 1 ) = 2 ∗ f ( n ) + f ( n − 1 ) f(n+1)=2*f(n)+f(n-1) f(n+1)=2∗f(n)+f(n−1)
类似斐波那契数列的式子,结论有一个是形如 f ( n + 1 ) = a ∗ f ( n ) + b ∗ f ( n − 1 ) f(n+1)=a*f(n)+b*f(n-1) f(n+1)=a∗f(n)+b∗f(n−1)的式子均满足 g c d ( f ( a ) , f ( b ) ) = f ( g c d ( a , b ) ) gcd(f(a),f(b))=f(gcd(a,b)) gcd(f(a),f(b))=f(gcd(a,b))
那么接下来就和51nod1355是一样的了
感觉直接抄上去就能过啊…
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(LL x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(LL x){write(x);putchar('\n');}
const int MAXN=3000005;
LL f[MAXN],g[MAXN],ans,mod;
LL pow_mod(LL a,LL b)
{
LL ret=1;
while(b)
{
if(b&1)ret=ret*a%mod;
a=a*a%mod;b>>=1;
}
return ret;
}
int n;
int main()
{
int T=read();while(T--)
{
n=read();mod=read();
f[1]=g[1]=1;
for(int i=2;i<=n;i++)f[i]=g[i]=(2*f[i-1]+f[i-2])%mod;
for(int i=1;i<=n;i++)
{
LL inv=pow_mod(g[i],mod-2);
for(int j=2;i*j<=n;j++)g[i*j]=g[i*j]*inv%mod;
}
ans=0;LL temp=1;
for(int i=1;i<=n;i++)
{
temp=temp*g[i]%mod;
ans=(ans+temp*i)%mod;
}
pr2(ans);
}
return 0;
}

本文探讨了一种特定的数列求和问题,在模P意义下计算序列的和,利用数学归纳法推导出数列的递推公式,并通过编程实现高效的计算方法。文章详细解析了数列的性质,提供了完整的代码实现。
365

被折叠的 条评论
为什么被折叠?



