FZU 2236

中文题

显然要弄个dp出来

数据这么大 先离散化一下

dp[i] 以i为结尾的子序列数目

所有的数目加起来就是答案 

dp[i]   =   dp[1...i-1] 加起来

树状数组维护下   线段树莫名其妙超时  

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<set>
#include<string>
#include<map>

using namespace std;
typedef long long LL;

#define inf 1e9
#define MAXN 200010
#define mod 1000000007

struct node
{
    int num,pos;
}z[MAXN];
int tree[MAXN];
int now[MAXN];
bool cmp(node a,node b)
{
    return a.num<b.num;
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(tree,0,sizeof(tree));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&z[i].num);
      //      y[i]=z[i].num;
            z[i].pos=i;
        }
        sort(z+1,z+n+1,cmp);

        now[z[1].pos]=1;
        int cnt=1;
   //     for(int i=1;i<=n;i++)
     //       printf("%d ",z[i].pos);
     //   printf("
");
        for(int i=2;i<=n;i++)
        {
            if(z[i].num!=z[i-1].num)
            {
                now[z[i].pos]=++cnt;
            }
            else
            {
                now[z[i].pos]=cnt;
            }
        }
    //    for(int i=1;i<=n;i++)
     //       printf("%d ",now[i]);
      //
      //   printf("
");
        //printf("%d
",now[1]);
        for(int i=1;i<=n;i++)
        {
            int a=1,b;
            b=now[i];
            //printf("%d
",b);
            for(int j=b-1;j;j -= (j & -j))
            {
                 a=(a+tree[j])%mod;
            }
            for(int j=b;j<=cnt;j += (j & -j))
            {
                tree[j]=(tree[j]+a)%mod;
            }
        }
        //printf("1");
       // printf("%d
",cnt);
       // for(int i=1;i<=cnt;i++)
        //    printf("%d ",tree[i]);
        int ans=0;
        for(int i=cnt;i;i -= (i & -i))
        {
            ans=(ans+tree[i])%mod;
        }
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cherryMJY/p/6443745.html