upc 9325 序列本质

9325: 序列本质

时间限制: 1 Sec  内存限制: 128 MB
提交: 29  解决: 18
[提交] [状态] [讨论版] [命题人:admin]
题目描述
给定序列A,求出A中本质不同的子序列(包含空的子序列)个数模10 9+7的结果.
一个序列B是A的子序列需要满足A删掉某些元素后能够得到B.
两个子序列中对应位置的数都相同我们就认为这两个子序列本质相同.

 

输入
第一行包含一个整数N,代表序列的长度.接下来一行N个整数,第i个数代表Ai.

 

输出
输出一个整数代表答案。

 

样例输入
5
2 3 1 3 2

 

样例输出
27

 

提示

对于20%的数据,N≤10.
对于40%的数据,N≤20
对于70%的数据,N≤100000,1≤Ai≤100
对于100%的数据,N≤1000000,1≤Ai≤N

 

来源/分类

 

题意:

  中文题意不多解释了。

分析

            2  3  1  3  2

以a[i]结尾的序列 1   1+1   3+1   7+1   13+1             (用p[i]记录)

1~i构成的子序列 1     1+2   3+4   8+7-2 13+14-1=26 (用q[i]记录)

对于p[i] :相当于在p[i-1]的所有序列的末尾加上a[i]。

对于q[i] :p[i]加上1 ~ i-1的子序列个数。

///  author:Kissheart  ///
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e6+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
int n;
int vis[MAX],a[MAX];
ll p[MAX],q[MAX];
int main()
{
    ll ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    p[1]=1;
    q[1]=1;
    vis[a[1]]=1;
    for(int i=2;i<=n;i++)
    {
        ya
        if(!vis[a[i]])
        {
            vis[a[i]]=i;
            p[i]=(q[i-1]+1)%mod;
            q[i]=(q[i-1]+p[i])%mod;
        }
        else
        {
            p[i]=(q[i-1]+1)%mod;
            q[i]=(q[i-1]+p[i])%mod;
            q[i]=((q[i]-p[vis[a[i]]])%mod+mod)%mod;
            //printf("%d %lld\n",vis[a[i]],p[vis[a[i]]]);
            vis[a[i]]=i;

        }
        //printf("%lld %lld\n",p[i],q[i]);
    }
    printf("%lld\n",q[n]+1);
    return 0;
}
View Code

 

 

转载于:https://www.cnblogs.com/Kissheart/p/9939719.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值