zoukankan      html  css  js  c++  java
  • [CF314C](Sereja and Subsequences)

    • 题意

    给你一个序列

    把这个序列的每一个不下降子序列拿出来

    对于每一个子序列,一个可行序列为:

    1.由正整数组成,长度和原子串相同

    2.不大于原子串

    求所有,所有的可行串

    • solution

    dp

    (dp_i)为以i为结尾的所有可行串的总数

    对于最简单的严格单调递增序列有(即样例2)

    (dp_i)=( (sum^{i-1}_{r=1}) (dp_r))*(dp_i)+(dp_i)

    但是重复怎么办?

    我们减去上一个重复点的dp值(推荐手模一下以便理解)

    举个例子

    3

    1 2 2

    这个序列,(dp_1)=1,(dp_2)=(1)$ imes (2+2=4,)dp_3(=(1+4)) imes(2+2-)dp_2$=8

    但是序列递减部分怎么办,不加就可以了嘛qwq

    但是时间复杂度(n^2)怎么办(syk:还不简单),用树状数组维护一下就降下来辣

    如上

    • code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define int long long
    #define lowbit(x) (x&-x)
    using namespace std;
    const int mod=1000000007;
    int tree[2000005*4];
    int dp[2000005];
    int from[2000005];//from 即上一个重复点的dp值
    int a[200005];
    int n,poss=1,ans=0;
    void add(int x,int k) {for(x;x<=2000000;x+=lowbit(x))tree[x]+=k,tree[x]%=mod;}
    int sum(int k) {
        int anss=0;
        for(k;k;k-=lowbit(k))anss+=tree[k],anss=(anss%mod+mod)%mod;
        return anss;
        }
    signed main(){
      scanf("%lld",&n);
      memset(from,-1,sizeof(from));
      for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
      for(int i=1;i<=n;i++){
         dp[i]=(sum(a[i])*a[i]%mod+a[i])%mod;//sum(a[i])这样就可以保证加的都是小于等于a[i]的
         if(from[a[i]]!=-1)dp[i]-=from[a[i]];
         dp[i]=(dp[i]%mod+mod)%mod;
         ans+=dp[i];
         ans=(ans%mod+mod)%mod;
         from[a[i]]=(sum(a[i])*a[i]+a[i])%mod;
         add(a[i],dp[i]);//注意传的是a[i]而不是i
         } 
      cout<<ans%mod;
      }
    
  • 相关阅读:
    安全测试的概述和用例设计
    性能测试(四)常见调优
    性能测试(三)常见的性能测试缺陷
    Jmeter(七)六种参数化的方式
    Jmeter(六)所有的断言
    接口测试的问题解答
    ES学习
    flutter 之BottomNavigationBar属性
    flutter StaggeredGridView.countBuilder 上方取消空白
    flutter升级、回退到指定版本---mac版
  • 原文地址:https://www.cnblogs.com/stepsys/p/10387978.html
Copyright © 2011-2022 走看看