zoukankan      html  css  js  c++  java
  • 【TJOI 2014】 上升子序列

    【题目链接】

               点击打开链接

    【算法】

               先考虑50分的做法 :

               f[i]表示以i结尾的本质不同的上升子序列的个数

               则f[i] = sigma(f[j]) (j < i,a[j] < a[i]),注意如果a[j]不止一个,只需加上下标最大的即可,否则会重复计数

               那么,100分的做法,其实就是用树状数组来优化这个东西,注意因为a[i]最大10^9,所以要离散化

    【代码】

                

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e5 + 10;
    const int MOD = 1e9 + 7;
    
    int i,n,ans,len;
    int a[MAXN],num[MAXN],rk[MAXN],pre[MAXN],val[MAXN];
    
    class BinaryIndexedTree
    {
        private :
            int c[MAXN];
        public :
            inline int lowbit(int x)
            {
                return x & (-x);    
            }    
            inline void modify(int pos,int val)
            {
                int i;
                for (i = pos; i <= n; i += lowbit(i)) c[i] = (c[i] + val) % MOD;
            }
            inline int query(int pos)
            {
                int i,ans = 0;
                for (i = pos; i; i -= lowbit(i)) ans = (ans + c[i]) % MOD;
                return ans;
            }
    } BIT;
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;    
    }
    template <typename T> inline void write(T x)
    {
        if (x < 0) 
        {
            putchar('-');
            x = -x;    
        }    
        if (x > 9) write(x/10);
        putchar(x%10+'0');
    }
    template <typename T> inline void writeln(T x)
    {
        write(x);
        puts("");
    }
    
    int main()
    {
        
        read(n);
        for (i = 1; i <= n; i++)
        {
            read(a[i]);
            num[i] = a[i];
        }
        sort(num+1,num+n+1);
        len = unique(num+1,num+n+1) - num - 1;
        for (i = 1; i <= n; i++) rk[i] = lower_bound(num+1,num+len+1,a[i]) - num;
        for (i = 1; i <= n; i++)
        {
            val[i] = BIT.query(rk[i] - 1) + 1;
            BIT.modify(rk[i],(val[i] - val[pre[rk[i]]] + MOD) % MOD);
            pre[rk[i]] = i;    
        }
        
        for (i = n; i >= 1; i--)
        {
            if (pre[rk[i]]) 
            {
                ans = (ans + val[i] - 1) % MOD;
                pre[rk[i]] = 0;
            }
        }
        
        writeln(ans);
        
        return 0;
    }
  • 相关阅读:
    C# Lambda表达式
    .NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy
    SQL中的case when then else end用法
    WPF gif图片不动问题解决
    async(C# 参考)
    File类 ReadAllBytes() ReadAllLines() ReadAllText()
    二维码生成的常用数据格式
    在chrome console加入jquery库
    Reflector反编译WinForm程序重建项目资源和本地资源
    使用Settings.settings存储用户的个性化配置
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196342.html
Copyright © 2011-2022 走看看