• POJ3378:Crazy Thairs(动态规划+线段树或树状数组+离散化+高精度) java程序员


    Crazy Thairs
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 6092   Accepted: 1478

    Description

    These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ≤ N ≤ 50000) numbers, which  are no more than 109, Crazy Thair is a group of 5 numbers {i, j, k, l, m} satisfying:

    1. 1 ≤ i < j < k < l < m  N
    2. Ai < Aj < Ak < Al < Am

    For example, in the sequence {2, 1, 3, 4, 5, 7, 6},there are four Crazy Thair groups: {1, 3, 4, 5, 6}, {2, 3, 4, 5, 6}, {1, 3, 4, 5, 7} and {2, 3, 4, 5, 7}.

    Could you help Sempr to count how many Crazy Thairs in the sequence?

    Input

    Input contains several test cases. Each test case begins with a line containing a number N, followed by a line containing N numbers.

    Output

    Output the amount of Crazy Thairs in each sequence.

    Sample Input

    5
    1 2 3 4 5
    7
    2 1 3 4 5 7 6
    7
    1 2 3 4 5 6 7

    Sample Output

    1
    4
    21

    Source

    MYCode:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MAX 50010
    int list[MAX];
    int st[MAX];
    struct bign
    {
        char m[30];//note
        int len;
        void init()
        {
            memset(m,0,sizeof(m));
            len=1;//note
        }
    };
    bign add(bign aa,bign bb)
    {
        bign c;
        c.init();
        int len=aa.len>bb.len?aa.len:bb.len;
        int i;
        c.len=len;
        for(i=0;i<len;i++)
        {
            c.m[i]+=aa.m[i]+bb.m[i];
            if(c.m[i]>=10)
            {
                c.m[i+1]+=c.m[i]/10;
                c.m[i]%=10;
                if(i+2>len)
                c.len=i+2;
            }
        }
        return c;
    }
    struct node
    {
        int lt;
        int rt;
        bign v;
    }a[6][4*MAX];
    int v[MAX];
    bign num[6];
    int ct;
    void build(int s,int t,int step,int cur)
    {
        a[cur][step].lt=s;
        a[cur][step].rt=t;
        //a[cur][step].v=0;
        a[cur][step].v.init();//note
        if(a[cur][step].lt==a[cur][step].rt)
        return;
        int mid=(s+t)/2;
        build(s,mid,2*step,cur);
        build(mid+1,t,2*step+1,cur);
    }
    void modify(int s,int t,int step,bign val,int cur)
    {
        if(a[cur][step].lt==s && a[cur][step].rt==t)
        {
            //a[cur][step].v+=val;
            a[cur][step].v=add(a[cur][step].v,val);
            return;
        }
        if(a[cur][step].lt==a[cur][step].rt)return;
        int mid=(a[cur][step].lt+a[cur][step].rt)/2;
        if(t<=mid)
        modify(s,t,2*step,val,cur);
        else
        modify(s,t,2*step+1,val,cur);
        //a[cur][step].v=a[cur][2*step].v+a[cur][2*step+1].v;
        a[cur][step].v=add(a[cur][2*step].v,a[cur][2*step+1].v);
    }
    bign query(int s,int t,int step,int cur)
    {
        if(a[cur][step].lt==s&&a[cur][step].rt==t)
        {
            return a[cur][step].v;
        }
        if(a[cur][step].lt==a[cur][step].rt)return a[cur][step].v;
        int mid=(a[cur][step].lt+a[cur][step].rt)/2;
        if(t<=mid)
        return query(s,t,2*step,cur);
        else if(mid<s)
        return query(s,t,2*step+1,cur);
        else
        {
            return add(query(s,mid,2*step,cur),query(mid+1,t,2*step+1,cur));
        }
    }
    int search(int val)
    {
        int lt=1,rt=ct;
        while(lt<=rt)
        {
            int mid=(lt+rt)/2;
            if(list[mid]==val)
            return mid;
            if(list[mid]<val)
            lt=mid+1;
            else
            rt=mid-1;
        }
        return -1;
    }
       
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            memset(a,0,sizeof(a));
            int i,j;
            //int most=-1;//note
            for(i=1;i<=n;i++)
            {
                scanf("%d",&v[i]);
                st[i]=v[i];
                //if(v[i]>most)
                //most=v[i];
            }
            sort(st+1,st+n+1);
            ct=1;
            list[1]=st[1];
            for(i=2;i<=n;i++)
            {
                if(st[i]!=st[i-1])
                {
                    list[++ct]=st[i];
                }
            }
            for(i=1;i<=5;i++)
            build(1,ct,1,i);
            for(i=1;i<=n;i++)
            {
                //memset(num,0,sizeof(num));
                for(j=1;j<=4;j++)
                num[j].init();
                int id=search(v[i]);
                if(id>=2)
                {
                    for(j=1;j<=4;j++)
                    {
                        num[j]=query(1,id-1,1,j);
                    }
                }
                bign tp;
                tp.m[0]=1;
                tp.len=1;//note
                modify(id,id,1,tp,1);
                for(j=1;j<=4;j++)
                {
                    if(num[j].len!=1||num[j].len==1&&num[j].m[0]!=0)
                    modify(id,id,1,num[j],j+1);
                }
            }
            bign ans=query(1,ct,1,5);
            //printf("%d\n",ans);
            int len=ans.len;
            for(i=len-1;i>=0;i--)
            {
                printf("%d",ans.m[i]);
            }
            printf("\n");
        }
    }

    //未通过.

    动态规划+线段树+离散化+高精度计算

    MYCode:(树状数组版本,TLE)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MAX 50010
    int list[MAX];
    int st[MAX];
    struct bign
    {
        char m[50];//note
        int len;
        void init()
        {
            memset(m,0,sizeof(m));
            len=1;//note
        }
    };
    bign add(bign aa,bign bb)
    {
        bign c;
        c.init();
        int len=aa.len>bb.len?aa.len:bb.len;
        int i;
        c.len=len;
        for(i=0;i<len;i++)
        {
            c.m[i]+=aa.m[i]+bb.m[i];
            if(c.m[i]>=10)
            {
                c.m[i+1]+=c.m[i]/10;
                c.m[i]%=10;
                if(i+2>len)
                c.len=i+2;
            }
        }
        return c;
    }
    int v[MAX];
    bign num[6];
    int ct;
    bign c[6][MAX];
    int low_bit(int x)
    {
        return x&(-x);
    }
    void modify(int n,bign delta,int cur)
    {
        while(n<=ct)
        {
            //c[cur][n]+=delta;
            c[cur][n]=add(c[cur][n],delta);
            n+=low_bit(n);
        }
    }
    bign sum(int n,int cur)
    {
        bign s;
        s.init();
        while(n!=0)
        {
            //s+=c[cur][n];
            s=add(s,c[cur][n]);
            n-=low_bit(n);
        }
        return s;
    }
    int search(int val)
    {
        int lt=1,rt=ct;
        while(lt<=rt)
        {
            int mid=(lt+rt)/2;
            if(list[mid]==val)
            return mid;
            if(list[mid]<val)
            lt=mid+1;
            else
            rt=mid-1;
        }
        return -1;
    }

    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            memset(c,0,sizeof(c));
            int i,j;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&v[i]);
                st[i]=v[i];
            }
            sort(st+1,st+n+1);
            ct=1;
            list[1]=st[1];
            for(i=2;i<=n;i++)
            {
                if(st[i]!=st[i-1])
                {
                    list[++ct]=st[i];
                }
            }
            for(i=1;i<=n;i++)
            {
                //memset(num,0,sizeof(num));
                //for(j=1;j<=4;j++)
                //num[j].init();
                int id=search(v[i]);
                for(j=1;j<=4;j++)
                {
                    num[j]=sum(id-1,j);
                }
                bign tp;
                tp.m[0]=1;
                tp.len=1;//note
                modify(id,tp,1);
                for(j=1;j<=4;j++)
                {
                    modify(id,num[j],j+1);
                }
            }
            bign ans=sum(ct,5);
            //printf("%d\n",ans);
            int len=ans.len;
            for(i=len-1;i>=0;i--)
            {
                printf("%d",ans.m[i]);
            }
            printf("\n");
        }
    }

    //TLE 

    数据范围大,所以要离散化

    答案大,所以要高精度

    各种TLE,MLE,RE.

    用线段树或者是树状数组优化竟然还TLE,无语.

    有时间再改.
        
       

  • 相关阅读:
    动画效果(二)
    动画效果(一)
    高级事件(二)
    高级事件(一)
    事件对象(二)
    事件对象(一)
    使用jquery ajax代替iframe
    SQL语句汇总(终篇)—— 表联接与联接查询
    SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
    SQL语句汇总(二)——数据修改、数据查询
  • 原文地址:https://www.cnblogs.com/java20130725/p/3215878.html
Copyright © 2020-2023  润新知