• <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] 做離散化處理.

            當(dāng)然, 原數(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] );             // 找當(dāng)前元素的 hash 下標(biāo)   
                            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;
            }

             

             

            久久九九有精品国产23百花影院| 亚洲精品高清一二区久久| 久久国产亚洲精品| 久久综合精品国产一区二区三区| 色综合久久精品中文字幕首页 | 久久久亚洲欧洲日产国码aⅴ| 久久影视综合亚洲| 久久久国产99久久国产一| 久久久黄色大片| 久久国产色AV免费观看| 2021少妇久久久久久久久久| 69SEX久久精品国产麻豆| 99久久中文字幕| 国产—久久香蕉国产线看观看| 国产99久久九九精品无码| 精品久久久无码中文字幕| 日日狠狠久久偷偷色综合96蜜桃| 性高湖久久久久久久久AAAAA| 久久久久波多野结衣高潮| 久久精品国产99久久无毒不卡 | 久久精品国产亚洲AV大全| 久久精品成人免费网站| 精品视频久久久久| yy6080久久| 亚洲午夜久久影院| 欧美午夜A∨大片久久| 亚洲中文字幕无码久久精品1 | 国产精品美女久久福利网站| 久久久久女人精品毛片| 久久久久国产精品三级网 | 久久久久国产精品熟女影院| 99re久久精品国产首页2020| 久久久久九国产精品| 浪潮AV色综合久久天堂| 久久精品国产99久久丝袜| 久久综合给久久狠狠97色| 久久国产V一级毛多内射| 国产成人精品久久一区二区三区| 久久精品女人天堂AV麻| 丁香五月网久久综合| 久久久久青草线蕉综合超碰|