nyoj 1197——你会加吗?——————【快速幂、分治】
你会加吗?
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
-
给出两个整数A和N,计算(A + A^2 + A^3 + …… + A^(N - 1) + A^N)% 666666。
- 输入
- 多组测试数据。
每组数据包含两个整数A,N(0≤A,N≤10^18)。 - 输出
- 输出(A + A^2 + A^3 + …… + A^(N - 1) + A^N)% 666666是多少,每组数据占一行。
- 样例输入
-
2 5 10 20
- 样例输出
-
62 110
解题思路:对于求解A+A2+A3+A4+A5+An/2+A(n/2+1)...+An。
我们总可以化成:当n%2==1,(A1+A2+A3...+An/2)+An/2*(A1+A2+A3+...An/2)+An。
即(A1+A2+A3...+An/2)*(An/2+1)+An。
当n%2==0,(A1+A2+A3...+An/2)+An/2*(A1+A2+A3+...An/2)。
即(A1+A2+A3...+An/2)*(An/2+1)。
然后就可以分治求解。#include<bits/stdc++.h> using namespace std; #define LL long long const LL mod=666666; LL Pow(LL a,LL x){ //快速幂 LL ret=1; while(x){ if(x&1) ret=ret*a%mod; a=a*a%mod; x>>=1; } return ret; } LL calcu(LL a,LL n){ //分治 if(n==1) return a; LL ret=calcu(a,n/2);//分治部分的返回值 ret=ret*(1+Pow(a,n/2))%mod; if(n%2==1) //n如果为奇数需再加上a^n ret= (ret+Pow(a,n))%mod; return ret; } int main(){ LL a,n; while(scanf("%lld%lld",&a,&n)!=EOF){ LL ans= calcu(a%mod,n); printf("%lld\n",ans); } return 0; }
学学学 练练练 刷刷刷