• <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原創, 轉帖請注明 : 轉載自 ______________白白の屋    

             

            題目地址:

            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
             

            題目分析 :

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

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

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

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

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

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

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

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

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

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

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

             

            代碼如下 :

            /*
            MiYu原創, 轉帖請注明 : 轉載自 ______________白白の屋
                      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 的第一個數 
                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 的第一個數 
                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 ){               // 數據 離散化 
                            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 的第一個數 
                            int tail = find2 ( num2[i] - D );        // 找 >= num2[i] - D  的第一個數 
                            int val = quy ( pre ) - quy ( tail - 1 ) + 1;  // 區間 [ num2[i] - D, num2[i] + D ] 的元素個數 + 新增的一個元素 
                            modify ( pos, val % MOD );
                       }
                       cout << ( quy ( nCount ) - N  ) % MOD << endl;  //以 一個元素 的 [ elem - D, elem + D ] 計算, 題目要求 k >= 2, 減掉 N 個 
                }
                return 0;
            }

             

             

            影音先锋女人AV鲁色资源网久久| 一本久久a久久精品综合夜夜| 色综合久久88色综合天天 | 天天综合久久一二三区| 伊人久久大香线蕉AV色婷婷色| 久久婷婷五月综合97色| 国产精品久久久久jk制服| 亚洲天堂久久精品| 久久91精品国产91| 久久99免费视频| 久久久久久久久久久久久久| 精品久久久噜噜噜久久久| 日韩精品无码久久一区二区三| 午夜精品久久久久久99热| 久久国产福利免费| 国产精品久久久久jk制服| 久久精品人人做人人爽电影| 久久se精品一区二区| 亚洲中文字幕无码一久久区| 很黄很污的网站久久mimi色| 精品人妻久久久久久888| 亚洲国产成人乱码精品女人久久久不卡 | 久久午夜免费视频| 色噜噜狠狠先锋影音久久| 亚洲午夜久久久影院伊人| 亚洲国产日韩欧美综合久久| 国产精品成人精品久久久| 久久精品免费一区二区三区| 色综合久久无码五十路人妻| 久久久无码精品午夜| 久久99精品久久久久久野外 | 精品精品国产自在久久高清| 久久人人爽人人爽人人片AV高清| 超级碰久久免费公开视频| 老司机国内精品久久久久| 国产国产成人精品久久| 久久久无码精品亚洲日韩按摩| 久久天天躁狠狠躁夜夜不卡| 亚洲精品国产第一综合99久久| 99热成人精品免费久久| 国产精品久久久99|