POJ 3378

题目链接

查找长度为5的上升序列总数

用的树状数组+高精度

用树状数组求在i前面比i小的数有几个

用的4个树状数组,A[i][j]表示长度为i的以j为结尾的个数,A[i][j]=A[i-1][1....flag[n]]

对数组下标不能为0一直不太理解,会发生死循环


 

#include <cstdio>

#include <iostream>

#include <algorithm>

#include <cstring>

using namespace std;

#define N 50005

#define MOD 10000

struct e{

    int w,id;

    bool operator <(const e &v) const

    {

        return w<v.w;

    }

}a[N];

__int64 A[4][N];

int flag[N],ans[10],n;

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

void update(int x,int y,__int64 w)

{

    while(y<n)

    {

        A[x][y]+=w;

        y+=lowbit(y);

    }



}

__int64 getsum(int x,int y)

{

    __int64 sum=0;

    while(y>0)

    {

        sum+=A[x][y];

        y-=lowbit(y);

    }

    return sum;

}

int ans_sum(__int64 w)  //高精度取模

{

    int i;

    i=0;

    while(w>0)

    {

        ans[i]+=w%MOD;

        if(ans[i]>=MOD)

        {

            ans[i]-=MOD;

            ans[i+1]++;

        }

        w/=MOD;

        i++;

    }

}

int main()

{

    int i,j;

    while(scanf("%d",&n)!=EOF)

    {

      //  memset(arr,0,sizeof(arr));

        for(i=1;i<=n;i++)

        {

            scanf("%d",&a[i].w);

            a[i].id=i;

        }

        sort(a,a+n);

        memset(ans,0,sizeof(ans));

        memset(A,0,sizeof(A));

        int mm=0;

        flag[a[1].id]=++mm;

        for(i=2;i<=n;i++)

        {

            if(a[i-1].w<a[i].w)

                flag[a[i].id]=++mm;

            else

                flag[a[i].id]=mm;

        }

        for(i=1;i<=n;i++)

        {

            __int64 x=1;

            for(j=0;j<4;j++)

            {

                update(j,flag[i],x); //x为长度为j-1的总数

                x=getsum(j,flag[i]-1);  

            }

            ans_sum(x); //对满足条件的进行求和

        }

        int t=0;

        for(i=9;i>=0;i--)

        {

            if(!t&&ans[i]>0)

            {

                printf("%d",ans[i]);

                t=1;

            }

            else if(t)

            printf("%04d",ans[i]);

        }

        if(!t) printf("0");

        printf("\n");

    }

    return 0;

}


 

 

你可能感兴趣的:(poj)