• 【BZOJ1717】&&【POJ3261】[Usaco2006 Dec]Milk Patterns 产奶的模式


    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1186  Solved: 640
    [Submit][Status][Discuss]

    Description

    农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。

    Input

    * Line 1: 两个整数 N,K。

    * Lines 2..N+1: 每行一个整数表示当天的质量值。

    Output

    * Line 1: 一个整数:N天中最长的出现了至少K次的模式的长度

    Sample Input

    8 2
    1
    2
    3
    2
    3
    2
    3
    1

    Sample Output

    4

    HINT

     

    Source

    Gold

    列表内某范姓同学和某尹姓同学差点坑害我 我就是要先贴单调队列

    先声明 这个题单调队列绝对是对的 因为他和二分完全等价 

    单调队列的话,我们考虑其向前k-1个数内的最小值(为什么不是k个?因为height数组的定义)

    答案是最小值内的最大值

    而分的话 我们考虑k-1个height数组内的最小值是否满足 满足即可

    可以发现 这两个条件完全可以转化 因为最小值满足时的最大值一定就是最小值内的最大值

    (md其实我这篇文章纯粹是发泄一下愤怒,坑了我两节课进去就为了验证这个本来就对的结论,最重要的是我拿一个没处理0的代码自信的说我绝对没错 mdzz 反正我改完了肯定是对的)

    顺便留组数据警示后人

    4 2

    1

    0

    0

    0

    答案是2

    为了发泄愤怒,我只贴单调队列的板子,二分的自己脑补一下应该能出来。

    /*In Search Of Life*/
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iomanip>
    #include<stack>
    #include<map>
    #include<set>
    #include<cmath>
    #define debug(x) cerr<<#x<<"="<<x<<endl
    #define INF 0x7f7f7f7f
    #define llINF 0x7fffffffffffll
    using namespace std;
    typedef pair<int,int> pii;
    typedef long long ll;
    inline int init()
    {
        int now=0,ju=1;char c;bool flag=false;
        while(1)
        {
            c=getchar();
            if(c=='-')ju=-1;
            else if(c>='0'&&c<='9')
            {
                now=now*10+c-'0';
                flag=true;
            }
            else if(flag)return now*ju;
        }
    }
    inline long long llinit()
    {
        long long now=0,ju=1;char c;bool flag=false;
        while(1)
        {
            c=getchar();
            if(c=='-')ju=-1;
            else if(c>='0'&&c<='9')
            {
                now=now*10+c-'0';
                flag=true;
            }
            else if(flag)return now*ju;
        }
    }
    int n,m,k,sa[1000005],auxsort[1000005],auxval[1000005],rank[1000005],auxa[1000005],auxb[1000005],height[1000005];
    int str[1000005];
    int getVal(int x[],int pos)
    {
        if(pos<=n)return x[pos];
        else return -1;
    }
    void getsa()
    {
        m=1000005;int *x=auxa,*y=auxb,cnt=0;
        for(int i=1;i<=n;i++)auxsort[x[i]=str[i]]++;
        for(int i=1;i<=m;i++)auxsort[i]+=auxsort[i-1];
        for(int i=n;i>=1;i--)sa[auxsort[x[i]]--]=i;
        for(int j=1;cnt<n;j<<=1,m=cnt)
        {
            cnt=0;
            for(int i=n-j+1;i<=n;i++)y[++cnt]=i;
            for(int i=1;i<=n;i++)if(sa[i]>j)y[++cnt]=sa[i]-j;
            for(int i=1;i<=n;i++)auxval[i]=x[y[i]];
            for(int i=0;i<=m;i++)auxsort[i]=0;
            for(int i=1;i<=n;i++)auxsort[auxval[i]]++;
            for(int i=1;i<=m;i++)auxsort[i]+=auxsort[i-1];
            for(int i=n;i>=1;i--)sa[auxsort[auxval[i]]--]=y[i];
            swap(x,y);cnt=x[sa[1]]=1;
            for(int i=2;i<=n;i++)
            {
                if(y[sa[i]]==y[sa[i-1]]&&getVal(y,sa[i]+j)==getVal(y,sa[i-1]+j))x[sa[i]]=cnt;
                else x[sa[i]]=++cnt;
            }
        }
        for(int i=1;i<=n;i++)rank[sa[i]]=i;
        cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(rank[i]==1)continue;
            if(cnt)cnt--;
            int j=sa[rank[i]-1];
            while(getVal(str,i+cnt)==getVal(str,j+cnt))++cnt;
            height[rank[i]]=cnt;
        }
        return;
    }
    int q[1000005];
    int head=1,tail=0;
    int minx[1000005];
    int ans=0;
    int main()
    {
        n=init();k=init();
        for(int i=1;i<=n;i++)str[i]=init();
        getsa();
        for(int i=1;i<=n;i++)
        {
            while(tail>=head&&height[q[tail]]>=height[i])
            {
                --tail;
            }
            q[++tail]=i;
            while(tail>=head&&q[tail]-q[head]>=k-1)
            {
                ++head;
            }
            minx[i]=height[q[head]];
            if(i>=k)ans=max(ans,minx[i]);
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Python之并发编程(三)生产者与消费者模型
    Python之并发编程(四)多线程(相关理论)
    cookiesession okenkey四大参数解析
    常见http返回的状态码
    for遍历用例数据时,报错:TypeError: list indices must be integers, not dict,'int' object is not iterable解决方法
    python中调用函数时,参数顺序与参数赋值问题
    自动化测试用例中的raise
    python --------简单的socket通话实现例子
    python---------------logging
    Monkey
  • 原文地址:https://www.cnblogs.com/redwind/p/6668759.html
Copyright © 2020-2023  润新知