Codeforces 185A 题解

本文探讨了一种使用递归与矩阵快速幂算法解决特定几何级数问题的方法,通过分析三角形的变化规律,推导出了计算任意状态下朝上三角形数量的公式,并提供了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意简述

blog1.png

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

数据

输入
2
输出
10

思路

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

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

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

a[i]=3a[i−1]+b[i−1]b[i]=3b[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=1i=1i=1时,a[i]=1,b[i]=0a[i]=1,b[i]=0a[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)=1f(x)=2f(x−1) f(1)=1\\ f(x)=2f(x-1) f(1)=1f(x)=2f(x1)
易得f(x)=2xf(x)=2^{x}f(x)=2x
a[i]−b[i]=2xa[i]-b[i]=2^xa[i]b[i]=2x
所以,a[i]=a[i]+b[i]+a[i]−b[i]2=4n−2n2=22n−1+2n−1a[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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值