• <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>
            這個(gè)題目是Sherlock推薦我做的。
            題目意思是給一個(gè)長(zhǎng)度為n(n <= 100000)的序列,里面的數(shù)滿足1 <= a[i] <= n。要找一個(gè)最長(zhǎng)的連續(xù)子串,使得這個(gè)子串是1..k的一個(gè)排列。

            昨天晚上mmd想了個(gè)n^(3/2)的算法,今天Sherlock想了個(gè)nlogn的算法。我一直在考慮有沒有O(n)的算法。我覺得應(yīng)該有的。
            今天晚上吃飯的時(shí)候忽然想出來了。回來寫了果然AC。

            下面是我的算法:
            注意到滿足題目要求的序列必有如下性質(zhì):
            1。最大值等于長(zhǎng)度
            2。必含1
            3。序列和為k * (k + 1) / 2
            4。序列內(nèi)元素不重復(fù)
            如果一個(gè)序列同時(shí)滿足性質(zhì)3,4,那么一定符合題目要求。
            于是如果做了O(n)的預(yù)處理,可以用O(1)的時(shí)間驗(yàn)證某序列是否滿足題目要求。
            然后我的算法就順理成章了:
            1。預(yù)處理s[i],為序列的部分和
            2。預(yù)處理rl[i],為從i開始往右,最長(zhǎng)的不重復(fù)序列的末端的下標(biāo)
            3。預(yù)處理m[i],為從i開始,到i右邊的第一個(gè)1(或者最右端),這一段數(shù)的最大值。
            4。枚舉左端點(diǎn)lp,則lp到其右邊的第一個(gè)1(或者最右端)中的最大值為m[lp]。把m[lp]作為序列長(zhǎng)度,則序列的右端點(diǎn)為lp + m[lp] - 1。利用s[i]和rl[i]數(shù)組可以驗(yàn)證這段序列是否滿足題目要求,若滿足,就更新最優(yōu)解。
            5。把輸入序列反過來,重復(fù)步驟1-4。
            以上每步的時(shí)間復(fù)雜度都是O(n),故算法總的時(shí)間復(fù)雜度也是O(n)。

            下面是我的代碼

            /*************************************************************************
            Author: WHU_GCC
            Created Time: 2008-1-4 18:06:14
            File Name: spoj744.cpp
            Description: 
            ***********************************************************************
            */

            #include 
            <iostream>
            using namespace std;

            #define out(x) (cout << #x << ": " << x << endl)
            typedef 
            long long int64;
            const int maxint = 0x7FFFFFFF;
            const int64 maxint64 = 0x7FFFFFFFFFFFFFFFLL;
            template 
            <class T> void show(T a, int n) for (int i = 0; i < n; ++i) cout << a[i] << ' '; cout << endl; }
            template 
            <class T> void show(T a, int r, int l) for (int i = 0; i < r; ++i) show(a[i], l); cout << endl; }

            const int maxn = 100010;

            int n;
            int a[maxn];
            int s[maxn];
            int rl[maxn];
            int hash[maxn];
            int m[maxn];

            int calc()
            {
                s[
            0= 0;
                
            for (int i = 1; i <= n; i++)
                    s[i] 
            = a[i] + s[i - 1];

                memset(hash, 
            0sizeof(hash));
                
            for (int i = 1, j = 1; i <= n; i++)
                
            {
                    
            while (j <= n && hash[a[j]] == 0)
                        hash[a[j
            ++]] = 1;
                    rl[i] 
            = j - 1;
                    hash[a[i]] 
            = 0;
                }


                
            for (int i = n; i >= 1; i--)
                    
            if (a[i] == 1)
                        m[i] 
            = 1;
                    
            else if (i == n)
                        m[i] 
            = a[i];
                    
            else
                        m[i] 
            = max(m[i + 1], a[i]);

                
            int ret = 0;
                
            for (int i = 1; i <= n; i++)
                    
            if (rl[i] >= i + m[i] - 1 && s[i + m[i] - 1- s[i - 1== m[i] * (m[i] + 1/ 2)
                        ret 
            >?= m[i];
                
            return ret;
            }


            int main()
            {
                scanf(
            "%d"&n);
                
            for (int i = 1; i <= n; i++)
                    scanf(
            "%d"&a[i]);
                
            int ans = calc();
                reverse(a 
            + 1, a + n + 1);
                ans 
            >?= calc();
                printf(
            "%d\n", ans);
                
            return 0;
            }


            posted on 2008-01-04 20:45 Felicia 閱讀(909) 評(píng)論(11)  編輯 收藏 引用 所屬分類: 雜題
            Comments
            • # re: [雜題]SPOJ744
              wywcgs
              Posted @ 2008-01-04 22:57
              和我的想法很像,呵呵,緣分阿  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              Felicia
              Posted @ 2008-01-05 16:10
              嘿嘿,看來我們真是有緣  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744[未登錄]
              1
              Posted @ 2008-01-06 12:00
              這樣做如何:
              #define N 10000
              int a[N];
              bool fis[N];
              memset(fis, false, sizeof(fis));
              對(duì)于i, 由于1《=a[i] 《= n,所以,如果a[i-1]=a[i]-1,并且
              a[i]的前a[i]-1個(gè)元素剛好是1....a[i-1]的最后一個(gè)元素,那么a[i],就分設(shè)置fis[i] = true ,or false;
              這個(gè)做完后,再掃描一次,看看fis[i]為true的i中,哪個(gè)a[i]最大。
                回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              Felicia
              Posted @ 2008-01-06 13:52
              感覺你說得不是很清楚
              并且
              a[i]的前a[i]-1個(gè)元素剛好是1....a[i-1]的最后一個(gè)元素,那么a[i],就分設(shè)置fis[i] = true ,or false;

              這兩句是什么意思?
              而且有 N <= 100000,貌似你定義錯(cuò)了
                回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              2
              Posted @ 2008-01-06 15:21
              #define N 100000
              簡(jiǎn)單點(diǎn)定義一個(gè)bool數(shù)組fis[N];
              如果a[1...n]中存在從1到a[i]連續(xù)a[i]個(gè)數(shù),那么fis[i] = true;or fis[i] =false;

              那么f[i+1] = (a[i]==a[i+1]-1)&&(fis[i]);

              。  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              2
              Posted @ 2008-01-06 15:38
              看錯(cuò)題目了。。。。  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              Felicia
              Posted @ 2008-01-06 21:30
              暈  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              richardxx
              Posted @ 2008-01-23 18:57
              嗯,有點(diǎn)難度,好方法,受教了!!  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              Felicia
              Posted @ 2008-01-23 19:34
              看了你的blog了,真的非常贊!  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              gnaggnoyil
              Posted @ 2009-03-04 12:29
              Orz wh大牛.  回復(fù)  更多評(píng)論   
            • # re: [雜題]SPOJ744
              吳豪
              Posted @ 2009-04-29 15:55
              @gnaggnoyil
              .......................  回復(fù)  更多評(píng)論   
             
            久久午夜福利无码1000合集| 精品蜜臀久久久久99网站| 久久婷婷人人澡人人| 国产精品久久久香蕉| 一本久久a久久精品亚洲| 国产精品久久久久久久久| 久久久久久毛片免费看| 无码人妻少妇久久中文字幕蜜桃| 久久久精品免费国产四虎| 女同久久| 情人伊人久久综合亚洲| 伊人久久综合精品无码AV专区| 爱做久久久久久| 少妇人妻88久久中文字幕| 久久精品国产精品亚洲| 久久人人爽爽爽人久久久| 日日狠狠久久偷偷色综合96蜜桃| 国产精品禁18久久久夂久| 亚洲欧洲精品成人久久曰影片 | 久久精品国产精品亚洲精品| aaa级精品久久久国产片| 久久久久久久综合狠狠综合| 久久免费高清视频| 久久亚洲私人国产精品vA| 久久婷婷五月综合成人D啪| 久久久久国产一区二区| 精品精品国产自在久久高清 | 91精品国产91热久久久久福利| 久久天天躁狠狠躁夜夜不卡| 色婷婷久久久SWAG精品| 99久久精品久久久久久清纯| 国产成人无码久久久精品一| 亚洲狠狠婷婷综合久久蜜芽| 一本久久综合亚洲鲁鲁五月天| 久久精品国产99久久久香蕉| 色综合久久最新中文字幕| 国产精品久久久久影院嫩草| 国产精品久久久久久搜索| 国内精品久久久久久99蜜桃| 久久久老熟女一区二区三区| 无码国内精品久久人妻蜜桃|