zoukankan      html  css  js  c++  java
  • 最长不下降子序列

    这里写图片描述

    分析:
    在考场上的思路是对的:
    D的范围很小,所以总有循环的一天,
    这样我们处理出循环节,
    需要注意的是,循环节不一定从1开始
    比如说:1 4 2 5 3 2 5 3 循环节从第3位开始
    我在考场上把序列缩到:不循环部分+一个循环节
    长度设为n
    在序列上做最长不下降子序列,
    至于之后的循环节,他们对答案都可以贡献1

    然而挂的很惨

    看了一下大佬的ac程序
    ta的n是这样的:
    这里写图片描述
    (我天,这么大,然而人家A了,你能说什么呢。。。)

    好吧,n最大上了万位,
    求最长不降只能用nlongn
    然而我这个zz连最长不降nlogn都jj

    看一下大佬优美的写法

    int le=1;
    f[1]=a[1];
    for (i=2;i<=n;i++)
    {
        if (a[i]>=f[le]) f[++le]=a[i];   //直接接上
        else  f[upper_bound(f+1,f+1+le,a[i])-f]=a[i];
        //upper_bound  >的第一个数 
    }
    return le;

    %%%

    最后要注意在%剩的余数中,也有可能对ans贡献1

    这里写代码片
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    
    using namespace std;
    
    ll nn;
    int A,B,C,D,t;
    int p[1000010],beg,xh,n;
    ll a[1000010],f[1000010];
    
    void doit()  //nlongn
    {
        int i,j;
        ll ans=0;
        int le=1;
        f[1]=a[1];
        for (i=2;i<=n;i++)
        {
            if (a[i]>=f[le]) f[++le]=a[i];   //直接接上
            else  f[upper_bound(f+1,f+1+le,a[i])-f]=a[i];
            //upper_bound  >的第一个数 
        }
        if (n==nn)
        {
            printf("%d",le);    
            return;
        } 
        ans=(ll)le+(nn-n)/xh;
        int r=(nn-n)%xh;  //不构成循环的一小部分 
        if (r)
            for (i=0;i<r;i++)
                if (a[beg+r]>=f[le])  //f[le]是长度为le的最小结尾 
                {
                    ans++;
                    break;
                } 
        printf("%lld",ans);
    }
    
    void cl()
    {
        memset(p,0,sizeof(p));
        int i,j;
        int x=t;
        p[t]=1;   //出现的位置 
        a[1]=t;
        for (i=2;i<=nn;i++)
        {
            x=A*x*x+B*x+C;
            x%=D;
            if (p[x]) 
            {
                n=i-1;
                beg=p[x];  //循环开始的地方 
                xh=i-p[x];
                break;
            }
            p[x]=i;
            a[i]=x;
        }
        n=xh*(xh<beg-1 ? beg-1:xh)+beg-1;  //循环部分:不循环部分  乘上较长的部分 
        if (n>nn) n=nn;
        for (i=beg+xh;i<=n;i++) a[i]=a[i-xh];
        for (int i=1;i<=beg+xh;i++) printf("%d ",a[i]);
        puts("");
        doit();
    }
    
    int main()
    {
        //freopen("lis.in","r",stdin);  
        //freopen("lis.out","w",stdout);
        scanf("%lld",&nn);
        scanf("%d%d%d%d%d",&t,&A,&B,&C,&D);
        if (nn==1) printf("1
    ");
        else cl();
        return 0;
    }
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673451.html
Copyright © 2011-2022 走看看