• <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>

            【AHOI2013復仇】BZOJ2165

            Posted on 2013-01-01 15:39 Mato_No1 閱讀(527) 評論(0)  編輯 收藏 引用 所屬分類: BZOJ
            原題地址
            2013年第一題……紀念一下……

            設F[i][j]表示坐i次電梯到達房間j,最多能到幾樓,則有
            F[i][j]=max{F[i-1][k]+W[k][j]}, 0<=k<n;
            這里W[k][j]要注意,如果不存在從k到j的電梯,W[k][j]應設為-INF。
            這個方程顯然是可以用矩陣乘法來優化的。
            然后,問題就是求出最小的i使得F[i]的狀態中有值>=M的,這個可以二分(每次看當前解與W的(2^K-1)次方的運算結果,若有解則實際不進行這次運算,否則與W的2^K次方運算)……總時間復雜度是O(n3logM)的,對于本題可能要進行一些常數優化才能過(20個點,每個點5個數據,相當于100個點,時限只有40s),反正本沙茶是卡線過的。

            但是,本題有一個細節很重要,必須要說一下(因為本沙茶在這里卡了1h+)……那就是溢出問題……
            F[i][j]的值是有可能超過long long的范圍的,然而如果硬加高精度的話穩T,這時,在進行矩陣乘法(實際是加法)的時候,需要特判一下,如果這個和超過了INF(INF是~0Ull>>2,>1018),就取INF。這樣可能會破壞結合律,但是木有事,因為若兩個加數都是非負數,則不會破壞,若有負數,則一定表示無解(-INF),這個特判一下就行了(若兩個加數之中有負數,則結果取-INF)。

            代碼:
            #include <iostream>
            #include 
            <stdio.h>
            #include 
            <stdlib.h>
            #include 
            <string.h>
            using namespace std;
            #define re(i, n) for (int i=0; i<n; i++)
            #define re1(i, n) for (int i=1; i<=n; i++)
            #define re2(i, l, r) for (int i=l; i<r; i++)
            #define re3(i, l, r) for (int i=l; i<=r; i++)
            #define rre(i, n) for (int i=n-1; i>=0; i--)
            #define rre1(i, n) for (int i=n; i>0; i--)
            #define rre2(i, r, l) for (int i=r-1; i>=l; i--)
            #define rre3(i, r, l) for (int i=r; i>=l; i--)
            #define ll long long
            const int MAXN = 110, MAXLEN = 61;
            const ll INF = ~0Ull >> 2;
            int n;
            ll M, A[MAXLEN][MAXN][MAXN], W0[MAXN][MAXN], _[MAXN][MAXN], res;
            void mult(ll A0[][MAXN], ll B0[][MAXN])
            {
                re(i, n) re(j, n) _[i][j] 
            = -INF; ll __;
                re(i, n) re(j, n) re(k, n) 
            if (A0[i][k] >= 0 && B0[k][j] >= 0) {
                    __ 
            = A0[i][k] + B0[k][j];
                    
            if (__ > INF) __ = INF;
                    
            if (__ > _[i][j]) _[i][j] = __;
                }
            }
            void prepare()
            {
                re2(i, 
            1, MAXLEN) {
                    mult(A[i 
            - 1], A[i - 1]);
                    re(j, n) re(k, n) A[i][j][k] 
            = _[j][k];
                    mult(A[i], A[
            0]);
                    re(j, n) re(k, n) A[i][j][k] 
            = _[j][k];
                }
            }
            void solve()
            {
                re(i, n) re(j, n) 
            if (i == j) W0[i][j] = 0else W0[i][j] = -INF; bool FF; res = 0;
                rre(i, MAXLEN) {
                    FF 
            = 0; re(j, n) if (A[i][0][j] >= M) {FF = 1break;}
                    
            if (FF) continue;
                    mult(W0, A[i]);
                    FF 
            = 0; re(j, n) if (_[0][j] >= M) {FF = 1break;}
                    
            if (!FF) {
                        re(j, n) re(k, n) W0[j][k] 
            = _[j][k];
                        mult(W0, A[
            0]);
                        re(j, n) re(k, n) W0[j][k] 
            = _[j][k];
                        res 
            += 2ll << i;
                    }
                }
                FF 
            = 0; re(i, n) if (W0[0][i] >= M) {FF = 1break;}
                
            if (!FF) res++;
            }
            int main()
            {
                
            int tests;
                scanf(
            "%d"&tests);
                re(testno, tests) {
                    cin 
            >> n >> M;
                    re(i, n) re(j, n) {scanf(
            "%lld"&A[0][i][j]); if (!A[0][i][j]) A[0][i][j] = -INF;}
                    prepare();
                    solve();
                    cout 
            << res << endl;
                }
                
            return 0;
            }

            国产成人久久精品一区二区三区 | 国产精品女同一区二区久久| 日本欧美久久久久免费播放网| 天天躁日日躁狠狠久久| 99久久免费国产特黄| 久久久久久青草大香综合精品 | 99久久国产精品免费一区二区 | 久久久久久久久久久免费精品| 人人妻久久人人澡人人爽人人精品| 久久人人爽人人人人爽AV| 97久久香蕉国产线看观看| 狠狠精品久久久无码中文字幕| 无码AV波多野结衣久久| 99久久99久久精品国产片| 色天使久久综合网天天| 久久久久99精品成人片牛牛影视| 久久99亚洲网美利坚合众国| 国产精品日韩欧美久久综合| 国产午夜精品久久久久免费视| 欧美激情精品久久久久久| 亚洲一本综合久久| 东方aⅴ免费观看久久av| 午夜精品久久影院蜜桃| yellow中文字幕久久网| 久久91精品国产91久久小草| 久久天天躁夜夜躁狠狠| 欧美久久天天综合香蕉伊| 国产高潮久久免费观看| 99精品久久精品一区二区| 亚洲欧美成人综合久久久| 热99RE久久精品这里都是精品免费| 久久99热这里只有精品国产| 青青青青久久精品国产| 久久亚洲国产午夜精品理论片| 国产精品99久久99久久久| av无码久久久久不卡免费网站| 色综合久久中文字幕无码| 99久久国产综合精品女同图片| 麻豆亚洲AV永久无码精品久久| 亚洲va久久久噜噜噜久久天堂 | 精品久久久噜噜噜久久久 |