zoukankan      html  css  js  c++  java
  • 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("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    lc739
    POJ3280
    6.2
    5.30
    5.28
    5.26
    5.26
    5.25
    从0搭建vue项目
    docker安装jenkins并使用
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3279981.html
Copyright © 2011-2022 走看看