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

            ACM___________________________

            ______________白白の屋
            posts - 182, comments - 102, trackbacks - 0, articles - 0
            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(24)

            隨筆分類(332)

            隨筆檔案(182)

            FRIENDS

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            MiYu原創(chuàng), 轉(zhuǎn)帖請注明 : 轉(zhuǎn)載自 ______________白白の屋    

             

            題目地址:

            http://acm.hdu.edu.cn/showproblem.php?pid=3450 

            題目描述:

            Counting Sequences

            Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others)
            Total Submission(s): 312    Accepted Submission(s): 105


            Problem Description
            For a set of sequences of integers{a1,a2,a3,...an}, we define a sequence{ai1,ai2,ai3...aik}in which 1<=i1<i2<i3<...<ik<=n, as the sub-sequence of {a1,a2,a3,...an}. It is quite obvious that a sequence with the length n has 2^n sub-sequences. And for a sub-sequence{ai1,ai2,ai3...aik},if it matches the following qualities: k >= 2, and the neighboring 2 elements have the difference not larger than d, it will be defined as a Perfect Sub-sequence. Now given an integer sequence, calculate the number of its perfect sub-sequence.
             

            Input
            Multiple test cases The first line will contain 2 integers n, d(2<=n<=100000,1<=d=<=10000000) The second line n integers, representing the suquence
             

            Output
            The number of Perfect Sub-sequences mod 9901
             

            Sample Input
            4 2 1 3 7 5
             

            Sample Output
            4
             

            題目分析 :

            ( 線段樹 || 樹狀數(shù)組 ) + DP  

            可以使用線段樹 或 樹狀數(shù)組來做,  可惜本人現(xiàn)在還不會線段樹, 下面是 樹狀數(shù)組 解題的分析 :

            因為題目要求的 是 k >= 2 ,  而且 相鄰元素 之差的絕對值 不大于 d,  這里糾結(jié)了很久 , 一直沒明白 "and the

            neighboring 2 elements have the difference not larger than d" 這句話的意思, 英語水平太差了.  最后在

            Amb 的解釋下才明白,  0rz...........  

            為了使問題簡單化, 我們不凡討論 k >= 1 的情況:

             因為 輸入數(shù)據(jù)的范圍比較大,  2<=n<=100000,1<=d=<=10000000 , 所以先要將 數(shù)據(jù)排序后 用 hash[max] 做離散化處理.

            當然, 原數(shù)組需要另開一個數(shù)組保存起來. 處理完成后,  我們可以這樣理解 :   用樹狀數(shù)組 com[pos], ( pos 為 num 在 hash 數(shù)組中的位

            置 ) . 記錄 能與 num 構(gòu)成 完美串的個數(shù).     初始狀態(tài)的 完美子串 為0, 每次加入一個數(shù), 那么這個數(shù) num 與 比他小且差不超過d的第一

            個數(shù) 而且與 比他大且差不超過d的第一個數(shù)  構(gòu)成完美串 . 更新樹狀數(shù)組. 最后求出所有的子串和 sum,  因為算法是以 k >= 1 來做的,而

            題目要求 k >= 2, 也就是說, 對 N 個數(shù), 就多計算了 N 次, 因此 (sum - N ) % 9901 即為所求. ( 別忘了MOD....... )

             

            代碼如下 :

            /*
            MiYu原創(chuàng), 轉(zhuǎn)帖請注明 : 轉(zhuǎn)載自 ______________白白の屋
                      http://www.cnblog.com/MiYu
            Author By : MiYu
            Test      : 1
            Program   : 3450
            */

            #include <iostream>
            #include <algorithm>
            using namespace std;
            const int MAX = 100010;
            const int MOD = 9901;
            int nCount = 0;
            int com[MAX];
            int hash[MAX];
            int num1[MAX];
            int num2[MAX];
            int N,D;
            inline int low ( int x ) {
                   return x & ( -x );
            }
            void modify ( int x, int val ){     // 修改 
                 while ( x <= nCount ){
                        com[x] += val; x += low ( x );
                 }     
            }
            int quy ( int x ){                  // 查詢 
                int sum = 0;
                while ( x > 0 ){
                       sum += com[x]; x -= low ( x );
                }
                return sum ;
            }
            int find1 ( int val ){         // 二分 找 <= val 的第一個數(shù) 
                int beg = 1, end = nCount; int mid = ( beg + end ) >> 1; int res = mid;
                while ( beg <= end ){
                       if ( hash[mid] <= val ){
                            beg = mid + 1; res = mid;
                       }else{
                            end = mid - 1; 
                       }
                       mid = ( beg + end ) >> 1;
                }
                return res;
            }
            int find2 ( int val ){         // 二分 找 <= val 的第一個數(shù) 
                int beg = 1, end = nCount; int mid = ( beg + end ) >> 1; int res = mid;
                while ( beg <= end ){
                       if ( hash[mid] < val ){
                            beg = mid + 1;
                       }else{
                            end = mid - 1; res = mid;
                       }
                       mid = ( beg + end ) >> 1;
                }
                return res;
            }
            inline bool scan_d(int &num)      // 輸入 
            {
                    char in;bool IsN=false;
                    in=getchar();
                    if(in==EOF) return false;
                    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
                    if(in=='-'){ IsN=true;num=0;}
                    else num=in-'0';
                    while(in=getchar(),in>='0'&&in<='9'){
                            num*=10,num+=in-'0';
                    }
                    if(IsN) num=-num;
                    return true;
            }
            int main ()
            {
                while ( scan_d ( N ) && scan_d ( D ) ){
                       for ( int i = 0; i < N; ++ i ){
                            scan_d ( num1[i] );  num2[i] = num1[i];  
                       }
                       sort ( num1, num1 + N );
                       hash[1] = num1[0];  nCount = 1;
                       for ( int i = 1; i < N; ++ i ){               // 數(shù)據(jù) 離散化 
                            if ( num1[i] != num1[i-1] ) hash[++nCount] = num1[i];
                       }
                       memset ( com, 0, sizeof ( com ) );
                       for ( int i = 0; i < N; ++ i ){
                            int pos = find1 ( num2[i] );             // 找當前元素的 hash 下標   
                            int pre = find1 ( num2[i] + D );         // 找 <=  num2[i] + D 的第一個數(shù) 
                            int tail = find2 ( num2[i] - D );        // 找 >= num2[i] - D  的第一個數(shù) 
                            int val = quy ( pre ) - quy ( tail - 1 ) + 1;  // 區(qū)間 [ num2[i] - D, num2[i] + D ] 的元素個數(shù) + 新增的一個元素 
                            modify ( pos, val % MOD );
                       }
                       cout << ( quy ( nCount ) - N  ) % MOD << endl;  //以 一個元素 的 [ elem - D, elem + D ] 計算, 題目要求 k >= 2, 減掉 N 個 
                }
                return 0;
            }

             

             

            99久久99久久精品国产片果冻| 久久狠狠高潮亚洲精品| 国产精品亚洲美女久久久| 精品久久人人爽天天玩人人妻 | 一本大道加勒比久久综合| 精品久久久久国产免费| 日产精品99久久久久久| 久久久久久狠狠丁香| 亚洲中文久久精品无码| 久久久久亚洲AV无码专区网站| 国内精品伊人久久久久777| 91精品国产91久久久久久| 麻豆AV一区二区三区久久| 色婷婷综合久久久久中文字幕| 久久精品99久久香蕉国产色戒 | 亚洲精品国精品久久99热一| 日本一区精品久久久久影院| 亚洲国产精品无码久久一区二区| 久久精品国产精品亜洲毛片| 国产成人综合久久综合| 亚洲国产一成人久久精品| 中文字幕精品久久| 午夜精品久久久久久影视777 | 大蕉久久伊人中文字幕| 国内精品人妻无码久久久影院| 波多野结衣久久一区二区| 久久国产精品二国产精品| 国产精品内射久久久久欢欢| 99久久国产热无码精品免费| 青草国产精品久久久久久| 色婷婷久久综合中文久久蜜桃av| 久久久精品人妻一区二区三区蜜桃| 人妻中文久久久久| 亚洲人成电影网站久久| 欧美激情一区二区久久久| 亚洲欧洲精品成人久久曰影片| 久久精品一区二区影院| 无码乱码观看精品久久| 久久久久久久女国产乱让韩| 777午夜精品久久av蜜臀| 亚洲AV无码久久寂寞少妇|