HDU 4990 Reading comprehension

Reading comprehension

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2062    Accepted Submission(s): 821


Problem Description
Read the program below carefully then answer the question.
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>

const int MAX=100000*2;
const int INF=1e9;

int main()
{
  int n,m,ans,i;
  while(scanf("%d%d",&n,&m)!=EOF)
  {
    ans=0;
    for(i=1;i<=n;i++)
    {
      if(i&1)ans=(ans*2+1)%m;
      else ans=ans*2%m;
    }
    printf("%d\n",ans);
  }
  return 0;
}
 

Input
Multi test cases,each line will contain two integers n and m. Process to end of file.
[Technical Specification]
1<=n, m <= 1000000000
 

Output
For each case,output an integer,represents the output of above program.
 

Sample Input
1 10 3 100
 

Sample Output
1 5
 

Source
 

Recommend
heyang

題意:給一個程序,想出優化方法,題意一個很好理解
剛開始一直嘗試推出方程,自己太菜,= =,硬是推不出來,推公式能力還是太弱,還好公式不復雜,列舉幾個數後就明白了
1 2 5 10 21 ........         F(n)=F(n-1)+2*F(n-2)+1,建造矩陣就簡單了

1   0   0                          1
0   0   1            X           ai               
1   2   1                          ai+1

a1=1,a2=2

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

#define pi acos(-1.0)
#define eps 1e-10
#define pf printf
#define sf scanf
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define e tree[rt]
#define _s second
#define _f first
#define all(x) (x).begin,(x).end
#define mem(i,a) memset(i,a,sizeof i)
#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
#define mi ((l+r)>>1)
#define sqr(x) ((x)*(x))

const int inf=0x3f3f3f3f;
ll ans[4][4],a[4],p[4][4];
int m,n;

void multi(ll a[][4],ll b[][4])//矩陣乘法,相乘後的數組爲第一個數組
{
    ll tmp[4][4];
    mem(tmp,0);
    for1(i,3)
        for1(j,3)
            for1(k,3)
                tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j]%m)%m;//相乘可能爆int
    for1(i,3)
        for1(j,3)
            a[i][j]=tmp[i][j];
}

void init()//數組初始化
{
    mem(p,0);
    p[1][1]=p[2][3]=p[3][1]=p[3][3]=1;
    p[3][2]=2;
    mem(ans,0);
    for1(i,3)
        ans[i][i]=1;
}

int main()
{
    a[0]=1,a[1]=1,a[2]=2;
    while(~sf("%d%d",&n,&m))
    {
        init();//數組初始化
        if(n<3)//n小於3直接輸出
        {
            pf("%I64d\n",a[n]%m);
            continue;
        }
        n-=2;
        while(n)//快速冪
        {
            if(n&1)multi(ans,p);
            n>>=1;
            multi(p,p);
        }
        ll sum=(ans[3][1]*a[0]%m+ans[3][2]*a[1]%m+ans[3][3]*a[2]%m)%m;
        pf("%I64d\n",sum);
    }
    return 0;
}





發佈了73 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章