51nod 算法马拉松17 解题报告

B题(数学题:

  问(1+sqrt(2)) ^n  能否分解成 sqrt(m) +sqrt(m-1)的形式

如果可以 输出 m%1e9+7 否则 输出no  n<=1e18

  刚看题没思路 暴力一下吧 发现根本没有no的情况 那么就好办多了

所求的值序列为 1, 2, 9, 50, 289, 1682, 9801, 57122, 332929, 1940450, 11309769

设(1+sqrt(2)) ^n为 A_n+B_n*sqrt(2) ,则:

  A_n = A_(n-1)+2*B_(n-1)

  A_n = A_(n-1)+B_(n-1)

  那么所求值序列显然为A_n*A_n+(n&1)

我们需要求这个A_n 暴力肯定不行,看到上面的递推式可以想到矩阵快速幂---

这个矩阵构造也非常简单

/*

1 2      A_n    A_(n+1)

   *       =

1 1    B_n    B_(n+1)

*/

然后注意下细节

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
inline void r(ll&num){
    num=0;ll f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘)num=num*10+ch-‘0‘,ch=getchar();
    num*=f;
}
inline void r(int &num){
    num=0;int f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘)num=num*10+ch-‘0‘,ch=getchar();
    num*=f;
}
const long long N = 2;
const long long M = 1e9+7;
struct Matr
{
    long long line;
    long long a[N+1][N+1];
    Matr(){
        line=2;
        a[0][0] = 1; a[0][1] = 2;
        a[1][0] = 1; a[1][1] = 1;
    }
};
Matr isit(Matr x,long long c)  //矩阵初始化
{
    for(long long i=0;i<N;i++)
        for(long long j=0;j<N;j++)
            x.a[i][j]=c;
    return x;
}

Matr Matlab(Matr x,Matr s)  //矩阵乘法
{
    Matr ans;
    ans.line = x.line;
    ans=isit(ans,0);
    for(long long i=0;i<x.line;i++)
    {
        for(long long j=0;j<x.line;j++)
        {
            for(long long k=0;k<s.line;k++)
            {
                ans.a[i][j] = (ans.a[i][j]+x.a[i][k]*s.a[k][j])%M;
                ans.a[i][j]=(ans.a[i][j]+M)%M;
            }
        }
    }
    return ans;
}
long long Fast_Matrix(Matr tmp,long long n)
{
    if(n==1)
        return 1;
    if(n==0)
        return 1;
    if(n==2)
        return 3;
    n--;
    Matr ans,ch;
    ans.line = 2;
    ans.a[0][0] = 1;
    ans.a[0][1] = 0;
    ans.a[1][0] = 1;
    ans.a[1][1] = 0;
    while(n>0)
    {
        if(n%2)
        {
            ans=Matlab(ans,tmp);
        }
        tmp=Matlab(tmp,tmp);
        n/=2;
    }
    return (ans.a[0][0]+ans.a[0][1])%M;
}
int main()
{
    Matr T;
    long long n;
    cin>>n;
    long long x = Fast_Matrix(T,n);
    cout<<(x*x+(n&1))%M<<endl;
    return 0;
}

AC代码

时间: 2024-11-05 18:51:18

51nod 算法马拉松17 解题报告的相关文章

51Nod 算法马拉松21(迎新年)

这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过读后面的题. B完全二叉树的方差,大概看了一遍,好神的样子,跳过. C多项式?好吧没学过FFT和NTT的我肯定不会,跳跳跳. D最大值,哎呦这函数什么破玩意儿,看不懂,跳跳跳. E B君的射击,卧槽毕克大人您出题就算了出这么一道码农题是要闹那样,跳跳跳. F那些年,我们一起讲的故事,卧槽这特么简直就

随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率,想象为一个n维长方体,有两个平面与这个几何图形相割,于是就变成了求面(体)积问题,一般要去重,n维区域系数:s^n/n!,至于区间问题,直接前缀之差搞定 然后就是悲催的算法马拉松17F题了...其实是道好题来的,只是出题人不知世界上还有这题,然后某大牛把思路理清后把答案直接搬了过来 经典的1*2骨牌覆

51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就可以A.. 然后之后zcg以奇怪的二分方式发现了如何A掉第一题的第十个点(我记得貌似是什么第5000个数等于511? OwO 就这样没有任何思考含量全凭骗分黑科技过掉了第一题 OwO 然后zcg打开了第二题,发现第二题样例有点问题,然后就发了个帖子,直接去看第三题了 我去瞅了一眼,发现这不是gcd

51nod算法马拉松 contest7

A题 链接:http://www.51nod.com/contest/problem.html#!problemId=1417 推荐链接:http://blog.csdn.net/a837199685/article/details/45009337 设美女取得正面概率是p,反面就是(1-p),就是美女取一正一反和一反一正的概率相同,然后推出公式y=((a+b)/2+b)/(2*(a+b)); 1 #include<iostream> 2 #include<cstdio> 3 #i

51Nod 算法马拉松23 开黑记

惨啊--虽然开了半天黑,但是还是被dalao们踩了-- 第二次开黑,还是被卡在rank20了,我好菜啊--= = 写一写比赛经过吧-- 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是道数论题,看了E感觉有点意思,一看数据范围,咦怎么只有$50000$,再仔细看一看式子,手动分情况讨论之后得到一个结论-- 这题是水的线段树维护莫队啊= = 然后就开始码码码,由于一些脑残错误调了一会儿,然后就得到了这样的结果: 我坚信自己莫队的复杂度没错,然后就开始各种王逸松卡常,使用的卡常技巧包

51nod 算法马拉松4

http://www.51nod.com/contest/problemList.html#!contestId=9 D 装盒子 拓扑排序?

51NOD 算法马拉松15(脱欧专场) B君的游戏(博弈)

传送门 B君的游戏 wwwwodddd (命题人) 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 B君和L君要玩一个游戏.刚开始有n个正整数 ai . 双方轮流操作.每次操作,选一个正整数x,将其移除,再添加7个数字 x1,x2-x7 .要求对于 xi ,满足 0<= xi < x 且 x&xi=xi 注意0不能被选取,所以这个游戏一定会结束,而谁无法操作谁就失败. B君根据自己的经验,认为先手胜率高一点,所以B君是先手. B君想知道自己是否必胜. Input 第一

51NOD算法马拉松 最大值问题 离线预处理+set lower_bound

题目:http://www.51nod.com/contest/problem.html#!problemId=1349 题意:100000个数的序列,有100000次询问,每次问区间最大值大于等于k的区间有多少? 思路:一开始没看到"大于等于",想了很久也不会,原来看错题了.看错题害死人. 一般询问的问题,如果不能用线段树log(n)求出,那么就离线做. 首先将询问按从大到小排序,再将序列中的每个数排序,注意记录序号. 对于当前询问,每加进一个数,我需要找到它在加进的序列(按大小有序

51nod 算法马拉松4 D装盒子(网络流 / 二分图最优匹配)

装盒子 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 有n个长方形盒子,第i个长度为Li,宽度为Wi,我们需要把他们套放.注意一个盒子只可以套入长和宽分别不小于它的盒子,并且一个盒子里最多只能直接装入另外一个盒子 (但是可以不断嵌套),例如1 * 1 可以套入2 * 1,而2 * 1再套入2 * 2.套入之后盒子占地面积是最外面盒子的占地面积.给定N个盒子大小,求最终最小的总占地面积. Input 第一行一个数N表示盒子的个数. 接下来N行,每行两个正整数,表示每个盒子的长