比赛时我自己的做法是构造了矩阵..但是有个细节没想到...其实这个题比较简单的方法就是递推,很容易想到的写积个就得到F(n)=3*F(n-1)-1;
如果根据高中数学构造一个等比数列的话,即两边都+上k 得到 F(n)-1/2 为一个公比为3的等比数列.
可以得到F(n)=(3^n+1)*(x+y)/2
这里有个小技巧就是因为对1e8取模 2和1e8不互质没办法用逆元来求, 根据 (a/b)%mod=a%(b*mod)/b%mod; 可知我们要将 3^n对2*mod 取模即可。
#include<bits/stdc++.h>
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 100000000
#define inf 0x3f3f3f3f
#define exp 0.00000001
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll gcd(ll a,ll b)
{
return b==0?a:gcd(b,a%b);
}
ll quick(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)
{
res=res*a%(2*MOD);
}
a=a*a%(2*MOD);
b>>=1;
}
return res;
}
int main()
{
ll x,y,n;
while(~Rl(x))
{
Rl(y),Rl(n);
ll zz=(quick(3,n)+1)/2%MOD;
ll z=(x+y)%MOD;
ll ans=z*zz%MOD;
Pl(ans);
}
return 0;
}
这里在贴一下我自己的矩阵快速幂的代码,其实矩阵快速幂的话一般要两项以上的未知数再用比较好,一项的一般就得递推式.
根据上面的等式我构造一个
3 -1 和 初始 1 0
0 1 1 0
但是这里有个地方需要注意!!!!! 由于我在计算矩阵的时候对mod取模,但是我矩阵中有负数,取模之后会使原来的数小于这个负数,导致最后的结果是个负数!!!!! 好坑!!!!!
解决的办法就是将最后的结果 (ans%mod+mod)%mod;这就好比一个钟表 此时八点和-4点 都一样 要得到八点就是+12%12即可。
#include<bits/stdc++.h>
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define mod 100000000
#define inf 0x3f3f3f3f
#define exp 0.00000001
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
typedef struct
{
ll s[3][3];
}matrix;
matrix mul(matrix A,matrix B)
{ matrix ans;
memset(ans.s,0,sizeof(ans.s));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
{
ans.s[i][j]=(ans.s[i][j]+A.s[i][k]*B.s[k][j]%mod)%mod;
}
return ans;
}
matrix quick(ll k,matrix w)
{
matrix f;
CLR(f.s,0);
f.s[0][0]=1;
f.s[1][0]=1;
while(k)
{ if(k%2==1)
f=mul(w,f);
w=mul(w,w);
/*puts("f");
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
cout<<i<<' '<<j<<' ',Pl(f.s[i][j]);
}
Pi(k++);
puts("");
puts("w");
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
cout<<i<<' '<<j<<' ',Pl(w.s[i][j]);
}*/
k/=2;
}
//Pl(f.s[0][0]);
return f;
}
int main()
{
ll x,y,n;
while(~scanf("%lld %lld %lld",&x,&y,&n))
{
matrix w;
w.s[0][0]=3;
w.s[0][1]=-1;
w.s[1][0]=0;
w.s[1][1]=1;
matrix f;
f=quick(n,w);
/*for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
Pi(f.s[i][j]);
}*/
//Pl(f.s[0][0]);
ll zz=f.s[0][0]%mod;
ll ss=(x+y)%mod;
ll ans=zz*ss%mod;
ll ans2=(ans%mod+mod)%mod;
printf("%lld\n",ans2);
}
return 0;
}