poj 3378 Crazy Thairs dp

来源:互联网 发布:云印网络印刷平台 编辑:程序博客网 时间:2024/06/05 02:17
用树状数组优化转移复杂度,结果会超long long,要用高精度。
#include <iostream>#include <cstdio>#include <cstring>#include <set>typedef unsigned long long ll;using namespace std;const int maxn=5e4+9;ll tree[6][maxn],dp[maxn][6];int a[maxn];int n;typedef struct node{    int data,id;    bool operator <(const node &xx) const    {        if(data==xx.data)        return(id<xx.id);        return(data<xx.data);    }};int lowbit(int x){    return(x&-x);}void insert(int x,int t,ll tmp){    for(int i=x;i<=n;i+=lowbit(i))    tree[t][i]+=tmp;}ll getsum(int x,int t){    ll ans=0;    for(int i=x;i>=1;i-=lowbit(i))    ans+=tree[t][i];    return(ans);}int main(){    set <node> d;//    freopen("in.txt","r",stdin);    while(scanf("%d",&n)!=EOF)    {        d.clear();        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            node x;            x.data=a[i];            x.id=i;            d.insert(x);        }        int k=0,tmp;        for(set <node>::iterator i=d.begin();i!=d.end();i++)        {            if(i==d.begin()||i->data!=tmp) k++;            a[i->id]=k;            tmp=i->data;        }        memset(dp,0,sizeof(dp));        memset(tree,0,sizeof(tree));        for(int i=1;i<=n;i++)        {            dp[i][1]=1;            insert(a[i],1,dp[i][1]);            for(int j=1;j<=4;j++)            {                dp[i][j+1]=getsum(a[i]-1,j);                insert(a[i],j+1,dp[i][j+1]);            }        }        ll ans=0,ans1=0;        for(int i=1;i<=n;i++)        {            ans+=dp[i][5];            ans1+=ans/ll(1000000000000000);            ans%=1000000000000000;        }        if(ans1)        {            printf("%lld",ans1);            printf("%015lld\n",ans);        }        else        printf("%lld\n",ans);    }    return 0;}