栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

P3970 [TJOI2014]上升子序列

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

P3970 [TJOI2014]上升子序列

链接

题意

给你一个大小为n的序列,让你求上升子序列的个数,其中不能算上重复的元素,长度至少为2。

思路

这个跟之前做的那个P2344 [USACO11FEB]Generic Cow Protests G有点类似,这两个题的实质都是一个dp。
回到这个题,假设我们设dp[i]表示以第i个点为止,所求得的方案数,那么如果我们直接暴力,可以在O( N 2 N^2 N2)的时间复杂度内计算得到答案,但是这个题的标签是个数据结构,那么就可以往线段树或者树状数组上面靠(我目前只会这两个)。
题目中说了如果了上升子序列相同,那么只计算一次,意思是会存在重复的元素,那么就想到了离散化,但是我们如果单纯的离散化然后去重,直接计算的话,可能会漏掉一些情况,假如给你一个样例是2 3 5 1 2 4 5,我们去重后会得到2 3 5 1 4,得到的去重后的情况肯定就漏掉了一些情况,应为对于相同的两个数,如果这两个数之间还存在比第一次出现之前的那些数还小的情况,我们会直接忽略掉,显然是不能忽略掉的,那么我们不如单独来维护到位一个为止,所存在的方案,假设这个数已经出现过了,那么更新了答案之后直接将上一次出现的那个位置的方案数减去即可。然后我们就用树状数组添加即可。

#include 

#define int long long

using namespace std;

const int N = 1e5 + 10;
const int mod = 1e9 + 7;

int n;
int tr[N];
int lans[N], a[N], b[N], vis[N];
map cnt;

int lowbit(int x) { return x & -x; }

void add(int x, int k) { for (int i = x; i <= n; i += lowbit(i)) tr[i] = (tr[i] + k) % mod; }

int Sum(int x)
{
    int sum = 0;
    for (int i = x; i; i -= lowbit(i)) sum = (sum + tr[i]) % mod;
    return sum;
}

signed main()
{
    std::ios::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i <= n; i ++) { cin >> a[i]; b[i] = a[i]; }
    ///离散化去重
    sort(b + 1, b + 1 + n);
    int ans = 0;
    int tot = unique(b + 1, b + 1 + n) - b - 1;
    for (int i = 1; i <= tot; i ++) cnt[b[i]] = i;

    for (int i = 1; i <= n; i ++)
    {
        int tmp = cnt[a[i]];
        int val = Sum(tmp - 1);

        if (!vis[tmp])
        {
            ans = (ans + val) % mod;
            add(tmp, val + 1);
            lans[tmp] = val;
            vis[tmp] = 1;
            continue;
        }

        ans = (ans + val - lans[tmp]) % mod;
        add(tmp, (val - lans[tmp]) % mod);
        lans[tmp] = val;
    }

    cout << ans << endl;
    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1011830.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号