Codeforces 185A 题解

题意简述

blog1.png

一个三角形如图所示变化。初始状态(第0个状态)是一个大三角形,然后每一个三角形都会被4等分,分完就是下一个状态。求第 n n n( n n n的范围是 1 0 18 10^{18} 1018!!!)个状态中有多少个尖角朝上的三角形。对 1 0 9 + 7 10^9+7 109+7取模。

数据

输入
2
输出
10

思路

设第 i i i个状态中有 a [ i ] a[i] a[i]个朝上的, b [ i ] b[i] b[i]个朝下的。

首先每次4等分,三角形总数应该是不断 × 4 \times 4 ×4的。所以 a [ i ] + b [ i ] = 4 i a[i]+b[i]=4^i a[i]+b[i]=4i

我们发现,上一个状态中如果有一个朝下的,4等分之后会变成3个朝下的+1个朝上的。如果有一个朝上的,4等分之后会变成3个朝上的+1个朝下的。所以,我们珂以得到:

a [ i ] = 3 a [ i − 1 ] + b [ i − 1 ] b [ i ] = 3 b [ i − 1 ] + a [ i − 1 ] a[i]=3a[i-1]+b[i-1]\\ b[i]=3b[i-1]+a[i-1]\\ a[i]=3a[i1]+b[i1]b[i]=3b[i1]+a[i1]

这个式子有什么规律呢。。。
好像没有。
我们会想,如果知道 a [ i ] + b [ i ] a[i]+b[i] a[i]+b[i],那么只要知道 a [ i ] − b [ i ] a[i]-b[i] a[i]b[i]就珂以直接求出 a [ i ] a[i] a[i] b [ i ] b[i] b[i]了。
那么我们减减试试吧。。。
a [ i ] − b [ i ] = 3 ( a [ i − 1 ] − b [ i − 1 ] ) + ( b [ i − 1 ] − a [ i − 1 ] ) = 2 ( a [ i − 1 ] − b [ i − 1 ] ) a[i]-b[i]=3(a[i-1]-b[i-1])+(b[i-1]-a[i-1])=2(a[i-1]-b[i-1]) a[i]b[i]=3(a[i1]b[i1])+(b[i1]a[i1])=2(a[i1]b[i1])
显然,当 i = 1 i=1 i=1时, a [ i ] = 1 , b [ i ] = 0 a[i]=1,b[i]=0 a[i]=1,b[i]=0
f ( x ) = a [ x ] − b [ x ] f(x)=a[x]-b[x] f(x)=a[x]b[x],那么由上面的式子得
f ( 1 ) = 1 f ( x ) = 2 f ( x − 1 ) f(1)=1\\ f(x)=2f(x-1) f(1)=1f(x)=2f(x1)
易得 f ( x ) = 2 x f(x)=2^{x} f(x)=2x
a [ i ] − b [ i ] = 2 x a[i]-b[i]=2^x a[i]b[i]=2x
所以, a [ i ] = a [ i ] + b [ i ] + a [ i ] − b [ i ] 2 = 4 n − 2 n 2 = 2 2 n − 1 + 2 n − 1 a[i]=\frac{a[i]+b[i]+a[i]-b[i]}{2}=\frac{4^n-2^n}{2}=2^{2n-1}+2^{n-1} a[i]=2a[i]+b[i]+a[i]b[i]=24n2n=22n1+2n1
打快速幂就珂以了。

代码:

#include<bits/stdc++.h>
#define int long long
#define mod 1000000007
using namespace std;

int p2(int p,int m)//快速求2的幂
{
    int a=2;
    int r=1;
    while(p)
    {
        if (p&1) r=r*a%m;
        a=a*a%m,p>>=1;
    }
    return r;
}
int n;
void Solve()
{
    if (n==0)//特判这个!!!
    {
        puts("1");
        return;
    }
    printf("%I64d\n",(p2(2*n-1,mod)+p2(n-1,mod))%mod);
}

main()
{
    scanf("%I64d",&n);
    Solve();
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值