• <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>
            隨筆 - 97, 文章 - 22, 評(píng)論 - 81, 引用 - 0
            數(shù)據(jù)加載中……

            PKU 3378 Crazy Thairs

            題目鏈接:http://poj.org/problem?id=3378
            /*
            題意:
                給定N (1 <= N <= 50000) 個(gè)小于等于10^9的數(shù)Ai, 要求找出Crazy Thair的數(shù)量。
            Crazy Thair是一個(gè)五元組{i, j, k, l, m}滿足: 
            1. 1 <= i < j < k < l < m <= N
            2. Ai < Aj < Ak < Al < Am 

            解法:
                樹狀數(shù)組

            思路:
                可以參考以下這題的解法:
            http://www.shnenglu.com/menjitianya/archive/2011/04/06/143510.html
                那一題求得是非遞減數(shù)列的數(shù)量,沒有要求元素個(gè)數(shù),這題是要求元素個(gè)數(shù)一定要
            是5個(gè),我們還是可以寫出狀態(tài)轉(zhuǎn)移方程:
            dp[i][j] = sum{ dp[i-1][k], k<j, a[k] < a[j] } dp[i][j]表示長(zhǎng)度為i以j結(jié)尾的
            序列的數(shù)量,這題需要建立5個(gè)樹狀數(shù)組,sum這一步操作就可以通過樹狀數(shù)組的成段求
            和來做。每次求i-1的滿足情況的解,完畢后就將答案插入到i的樹狀數(shù)組中。
                當(dāng)長(zhǎng)度為5的時(shí)候就是最后的答案了,累加即可。
            */

            #include 
            <iostream>
            #include 
            <algorithm>
            using namespace std;

            typedef 
            int hugeint;
            const int Base = 10000
            const int Capacity = 7;

            struct xnum {
                
            int Len;
                
            int Data[Capacity];
                xnum() : Len(
            0{}
                xnum(
            const xnum& V) : Len(V.Len) {
                    memcpy(Data, V.Data, Len 
            * sizeof *Data);
                }

                xnum(
            int V) : Len(0
                    
            for (; V > 0; V /= Base) Data[Len++= V % Base;
                }

                xnum(
            char S[]);
                xnum
            & operator=(const xnum& V) 
                    Len 
            = V.Len;
                    memcpy(Data, V.Data, Len 
            * sizeof *Data); 
                    
            return *this;
                }

                
            int& operator[](int Index) return Data[Index]; }
                
            int operator[](int Index) const return Data[Index]; }
                
            void print(){
                    printf(
            "%d",Len==0?0:Data[Len-1]);
                    
            for(int i=Len-2;i>=0;i--)
                        
            for(int j=Base/10;j>0;j/=10)
                            printf(
            "%d",Data[i]/j%10);
                }

            }
            ;

            xnum::xnum(
            char S[]) {
                
            int I, J;
                Data[Len 
            = 0= 0;
                J 
            = 1;
                
            for (I = strlen(S)-1; I>=0; I--{
                    Data[Len] 
            += (S[I] - '0'* J;
                    J 
            *= 10;
                    
            if (J >= Base) J = 1, Data[++Len] = 0;
                }

                
            if (Data[Len] > 0) Len++;
            }


            int compare(const xnum& A, const xnum& B) {
                
            int I;
                
            if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;
                
            for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);
                
            if (I < 0return 0;
                
            return A[I] > B[I] ? 1 : -1;
            }


            xnum 
            operator+(const xnum& A, const xnum& B) {
                xnum R;
                
            int I;
                
            int Carry = 0;
                
            for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++)
                
            {
                    
            if (I < A.Len) Carry += A[I];
                    
            if (I < B.Len) Carry += B[I];
                    R[I] 
            = Carry % Base;
                    Carry 
            /= Base;
                }

                R.Len 
            = I;
                
            return R;
            }


            xnum 
            operator-(const xnum& A, const xnum& B) {
                xnum R;
                
            int Carry = 0;
                R.Len 
            = A.Len;
                
            int I;
                
            for (I = 0; I < R.Len; I++{
                    R[I] 
            = A[I] - Carry;
                    
            if (I < B.Len) R[I] -= B[I];
                    
            if (R[I] < 0) Carry = 1, R[I] += Base;
                    
            else Carry = 0;
                }

                
            while (R.Len > 0 && R[R.Len - 1== 0) R.Len--;
                
            return R;
            }


            xnum 
            operator*(const xnum& A, const int B) {
                
            int I;
                
            if (B == 0return 0;
                xnum R;
                hugeint Carry 
            = 0;
                
            for (I = 0; I < A.Len || Carry > 0; I++)
                
            {
                    
            if (I < A.Len) Carry += hugeint(A[I]) * B;
                    R[I] 
            = Carry % Base;
                    Carry 
            /= Base;
                }

                R.Len 
            = I;
                
            return R;
            }


            xnum 
            operator*(const xnum& A, const xnum& B) {
                
            int I;
                
            if (B.Len == 0return 0;
                xnum R;
                
            for (I = 0; I < A.Len; I++{
                    hugeint Carry 
            = 0;
                    
            for (int J = 0; J < B.Len || Carry > 0; J++{
                        
            if (J < B.Len) Carry += hugeint(A[I]) * B[J];
                        
            if (I + J < R.Len) Carry += R[I + J];
                        
            if (I + J >= R.Len) R[R.Len++= Carry % Base;
                        
            else R[I + J] = Carry % Base;
                        Carry 
            /= Base;
                    }
               
                }

                
            return R;
            }


            xnum 
            operator/(const xnum& A, const int B) {
                xnum R;
                
            int I;
                hugeint C 
            = 0;
                
            for (I = A.Len - 1; I >= 0; I--)
                
            {
                    C 
            = C * Base + A[I];
                    R[I] 
            = C / B;
                    C 
            %= B;
                }

                R.Len 
            = A.Len;
                
            while (R.Len > 0 && R[R.Len - 1== 0) R.Len--;
                
            return R;
            }


            xnum 
            operator/(const xnum& A, const xnum& B) {
                
            int I;
                xnum R, Carry 
            = 0;
                
            int Left, Right, Mid;
                
            for (I = A.Len - 1; I >= 0; I--{
                    Carry 
            = Carry * Base + A[I];
                    Left 
            = 0;
                    Right 
            = Base - 1;
                    
            while (Left < Right) {
                        Mid 
            = (Left + Right + 1/ 2;
                        
            if (compare(B * Mid, Carry) <= 0) Left = Mid;
                        
            else Right = Mid - 1;
                    }

                    R[I] 
            = Left;
                    Carry 
            = Carry - B * Left;
                }

                R.Len 
            = A.Len;
                
            while (R.Len > 0 && R[R.Len - 1== 0) R.Len--;
                
            return R;
            }


            xnum 
            operator%(const xnum& A, const xnum& B) {
                
            int I;
                xnum R, Carry 
            = 0;
                
            int Left, Right, Mid;
                
            for (I = A.Len - 1; I >= 0; I--{
                    Carry 
            = Carry * Base + A[I];
                    Left 
            = 0;
                    Right 
            = Base - 1;
                    
            while (Left < Right) {
                        Mid 
            = (Left + Right + 1/ 2;
                        
            if (compare(B * Mid, Carry) <= 0) Left = Mid;
                        
            else Right = Mid - 1;
                    }

                    R[I] 
            = Left;
                    Carry 
            = Carry - B * Left;
                }

                R.Len 
            = A.Len;
                
            while (R.Len > 0 && R[R.Len - 1== 0) R.Len--;
                
            return Carry;
            }


            istream
            & operator>>(istream& In, xnum& V) {
                
            char Ch;
                
            for (V = 0; In >> Ch;) {
                    V 
            = V * 10 + (Ch - '0');
                    
            if (cin.peek() <= ' 'break;
                }

                
            return In;
            }


            ostream
            & operator<<(ostream& Out, const xnum& V) {
                
            int I;
                Out 
            << (V.Len == 0 ? 0 : V[V.Len - 1]);
                
            for (I = V.Len - 2; I >= 0; I--
                    
            for (int J = Base / 10; J > 0; J /= 10
                        Out 
            << V[I] / J % 10;
                    
            return Out;
            }


            xnum gcd(xnum a,xnum b) 
            {
                
            if(compare(b,0)==0return a;
                
            else return gcd(b,a%b); 
            }


            int div(char *A,int B) {
                
            int I;
                
            int C = 0;
                
            int Alen=strlen(A);
                
            for (I = 0; I <Alen; I++)
                
            {
                    C 
            = C * Base + A[I]-'0';
                    C 
            %= B;
                }

                
            return C;
            }


            #define maxn 50010

            int n;
            xnum c[
            6][maxn];
            int val[maxn], bin[maxn], tot;

            int lowbit(int x) {
                
            return x & (-x);
            }


            void add(int idx, int pos, xnum v) {
                
            while(pos <= n) {
                    c[idx][pos] 
            = c[idx][pos] + v;
                    pos 
            += lowbit(pos);
                }

            }


            xnum sum(
            int idx, int pos) {
                xnum s 
            = 0;
                
            while(pos > 0{
                    s 
            = s + c[idx][pos];
                    pos 
            -= lowbit(pos);
                }

                
            return s;
            }


            int Bin(int v) {
                
            int l = 1;
                
            int r = tot;
                
            while(l <= r) {
                    
            int m = (l + r) >> 1;
                    
            if(bin[m] == v)
                        
            return m;
                    
            if(v > bin[m]) {
                        l 
            = m + 1;
                    }
            else
                        r 
            = m - 1;
                }

            }



            int main() {
                
            int i, j;
                
            while(scanf("%d"&n) != EOF) {
                    tot 
            = 0;
                    
            for(i = 1; i <= n; i++{
                        scanf(
            "%d"&val[i]);
                        bin[i] 
            = val[i];
                    }

                    sort(bin
            +1, bin+1+n);
                    
            for(i = 1; i <= n; i++{
                        
            if(i==1 || bin[i] != bin[i-1])
                            bin[ 
            ++tot ] = bin[i];
                    }

                    
            for(i = 0; i <= 5; i++{
                        
            for(j = 1; j <= n; j++)
                            c[i][j] 
            = 0;
                    }


                    
            for(i = 1; i <= n; i++{
                        val[i] 
            = Bin(val[i]);
                    }

                    xnum ans 
            = 0;
                    
            for(i = 1; i <= n; i++{
                        add(
            1, val[i], 1);
                        
            for(j = 2; j <= 5; j++{
                            xnum p 
            = sum(j-1, val[i]-1);
                            
            if(p.Len)
                                add(j, val[i], p);

                            
            if(j == 5{
                                ans 
            = ans + p;
                            }

                        }

                    }

                    ans.print();
                    puts(
            "");
                }

                
            return 0;
            }

            posted on 2011-04-07 13:16 英雄哪里出來 閱讀(1500) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 樹狀數(shù)組

            蜜臀av性久久久久蜜臀aⅴ麻豆| 久久久精品久久久久久| 国内精品伊人久久久久妇| 久久成人影院精品777| 久久精品国产99国产电影网| 亚洲av成人无码久久精品| 久久午夜无码鲁丝片秋霞| 久久国产AVJUST麻豆| 亚洲精品美女久久久久99| 热99RE久久精品这里都是精品免费| 久久久久久久综合综合狠狠| 国产亚洲精午夜久久久久久| 国产 亚洲 欧美 另类 久久| 99久久婷婷国产一区二区| 国产精品久久久久乳精品爆| 伊人久久综在合线亚洲2019| 国内精品久久久久久久久 | 亚洲一区二区三区日本久久九| 97精品久久天干天天天按摩| aaa级精品久久久国产片| 久久国产高清字幕中文| 18岁日韩内射颜射午夜久久成人 | 五月丁香综合激情六月久久| 亚洲国产精品无码久久久不卡 | 亚洲国产精品久久久久| 国产精品成人99久久久久91gav| 久久99精品国产麻豆蜜芽| 久久久久国产一区二区三区| 人妻少妇精品久久| 亚洲欧美日韩中文久久| 99999久久久久久亚洲| 国产 亚洲 欧美 另类 久久| 午夜精品久久久内射近拍高清| 久久久黄色大片| 99久久777色| 久久久久人妻一区精品果冻| 无码任你躁久久久久久老妇| 久久亚洲精精品中文字幕| 99久久综合国产精品二区| 伊人色综合久久天天人守人婷 | 久久久久久久久久久|