• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            bon

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              46 Posts :: 0 Stories :: 12 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(2)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            poj 2748

            這道題跟Fibonacci在解法上一樣,不過這道題特殊的地方在于測試數(shù)據(jù)非常多,用普通的做法(t*log200000000)會超時。

            推導到這一步:f[i]=3*f[i-1]-f[i-2],其中f[i]是輸入i時的解。
            最樸素的辦法就是對每個i都從0開始遞推。這樣最壞復雜度是O(t*200000000)。
            改進的辦法是,將遞推式寫成矩陣相乘的式子,具體見借助矩陣快速計算總結(jié)與。

            代碼還是比較簡單的:
             1 // 2748 matrix formula
             2 
             3 #include <iostream>
             4 
             5 using namespace std;
             6 
             7 int first[2]={1,1};
             8 int trans[2][2]={{3,-1},{1,0}};
             9 __int64 tmp[31][2][2];
            10 __int64 p[31];
            11 int e[31];
            12 int a[10000000];
            13 
            14 void init()
            15 {
            16     p[0]=1;
            17     int i,j;
            18     for(i=1;i<=30;i++) p[i]=2*p[i-1];
            19     tmp[0][0][0]=3,tmp[0][0][1]=-1,tmp[0][1][0]=1,tmp[0][1][1]=0;
            20     for(i=1;i<=30;i++){
            21         tmp[i][0][0]=(tmp[i-1][0][0]*tmp[i-1][0][0]+tmp[i-1][0][1]*tmp[i-1][1][0])%100000;
            22         tmp[i][0][1]=(tmp[i-1][0][0]*tmp[i-1][0][1]+tmp[i-1][0][1]*tmp[i-1][1][1])%100000;
            23         tmp[i][1][0]=(tmp[i-1][1][0]*tmp[i-1][0][0]+tmp[i-1][1][1]*tmp[i-1][1][0])%100000;
            24         tmp[i][1][1]=(tmp[i-1][1][0]*tmp[i-1][0][1]+tmp[i-1][1][1]*tmp[i-1][1][1])%100000;
            25     }
            26     a[0]=1;
            27     a[1]=1;
            28     for(i=2;i<10000000;i++){
            29         a[i]=(3*a[i-1]-a[i-2]+200000)%100000;
            30     }
            31 }
            32 
            33 int solve(int n)
            34 {
            35     memset(e,0,sizeof(e));
            36     int nn=n;
            37     int i=0;
            38     while(nn!=0){
            39         int x=nn%2;
            40         nn/=2;
            41         e[i++]=x;
            42     }
            43     __int64 res[2][2]={{1,0},{0,1}},t[2][2];
            44 
            45     for(i=0;i<=30;i++){
            46         if(e[i]){
            47             t[0][0]=res[0][0]*tmp[i][0][0]+res[0][1]*tmp[i][1][0];
            48             t[0][1]=res[0][0]*tmp[i][0][1]+res[0][1]*tmp[i][1][1];
            49             t[1][0]=res[1][0]*tmp[i][0][0]+res[1][1]*tmp[i][1][0];
            50             t[1][1]=res[1][0]*tmp[i][0][1]+res[1][1]*tmp[i][1][1];
            51             res[0][0]=t[0][0]%100000,res[0][1]=t[0][1]%100000,res[1][0]=t[1][0]%100000,res[1][1]=t[1][1]%100000;
            52         }
            53     }
            54     
            55     int ans=(res[0][0]+res[0][1]+200000)%100000;
            56     printf("%d\n",ans);
            57     return ans;
            58 }
            59 
            60 int main()
            61 {
            62     //printf("%d\n",(-11)%10);
            63     init();
            64     int t,n;
            65     /*
            66     scanf("%d",&t);
            67     while(t--){
            68         scanf("%d",&n);
            69         if(n<10000000) printf("%d\n",a[n]);
            70         else solve(n-1);
            71     }
            72     */
            73     int x,y;
            74     for(int i=2;i<2000000000;i++){
            75         if(i<10000000) {x=y,y=a[i];}
            76         else {x=y;y=solve(i-1);}
            77         if(x==1 && y==1){printf("period=%d\n",i);break;}
            78     }
            79     return 1;
            80 }


            最后還是看了discuss里的解法,f[i]其實是以75000為循環(huán)節(jié):f[75000]=f[0],f[75001]=f[1]且f是2階的遞推式。編程算出前10000000個數(shù),然后逐個枚舉就能找出循環(huán)節(jié)。

            這道題給我影響深刻的地方在于可以找循環(huán)節(jié)。

            代碼非常簡單:
             1 // 2748 matrix formula
             2 
             3 #include <iostream>
             4 
             5 using namespace std;
             6 
             7 int a[75000];
             8 
             9 void init()
            10 {
            11     a[0]=1;
            12     a[1]=1;
            13     for(int i=2;i<75000;i++){
            14         a[i]=(3*a[i-1]-a[i-2]+200000)%100000;
            15     }
            16 }
            17 int main()
            18 {
            19     init();
            20     __int64 t,n;
            21     scanf("%I64d",&t);
            22     while(t--){
            23         scanf("%I64d",&n);
            24         if(n<75000) printf("%d\n",a[n]);
            25         else printf("%d\n",a[n%75000]);
            26     }
            27     return 1;
            28 }
            posted on 2008-06-09 15:29 bon 閱讀(609) 評論(0)  編輯 收藏 引用 所屬分類: Programming Contest
            Google PageRank 
Checker - Page Rank Calculator
            亚洲AV成人无码久久精品老人| 久久国产精品偷99| 日韩人妻无码精品久久久不卡| 蜜臀av性久久久久蜜臀aⅴ麻豆| 亚洲国产精品无码久久久蜜芽| 99久久国产主播综合精品| 久久青青草视频| 久久精品无码一区二区三区日韩 | 国产精品欧美久久久久无广告| 狠狠色丁香婷婷久久综合五月| 精品久久一区二区| 色欲综合久久中文字幕网| 欧美亚洲国产精品久久| 亚洲第一永久AV网站久久精品男人的天堂AV | 人妻少妇久久中文字幕| 亚洲AV日韩精品久久久久| 久久99精品久久久久久9蜜桃 | 99久久精品免费看国产一区二区三区| 色老头网站久久网| 日产精品久久久久久久性色| 无码人妻久久一区二区三区蜜桃 | 久久综合给合久久狠狠狠97色 | 亚洲va久久久噜噜噜久久男同| 国内精品欧美久久精品| 久久精品人人做人人妻人人玩| 久久中文骚妇内射| 久久久噜噜噜www成人网| 国产精品永久久久久久久久久| 国产成人精品三上悠亚久久| 久久精品无码一区二区app| 久久99国产精品久久久| 久久九九久精品国产免费直播| 日本久久久精品中文字幕| 久久精品aⅴ无码中文字字幕重口| 品成人欧美大片久久国产欧美| 久久亚洲AV成人无码国产| 亚洲AV日韩精品久久久久久久| 精品伊人久久大线蕉色首页| 亚洲狠狠婷婷综合久久久久| 久久久噜噜噜久久| 亚洲精品乱码久久久久久蜜桃图片 |