zoukankan      html  css  js  c++  java
  • 一道好题

    一只熊孩纸安利了一道题QAQ一开始还说错题意了QAQ

    题意:

       

      

       题意可以解释为,给你一个1~n的排列a[],求一个i,使xi=(∑(j<i&&a[j]>a[i]) 1)最大,要求O(n)

    sol:

       我这么蒟蒻显然想不出来啊,还说标程就10几行什么的QAQ,果断请教大爷去了

       首先对于该排列建立一个二维矩阵如图所示,横坐标为i,纵坐标为a[i]

       那么答案即为一个点左上方点的个数

       

       因为一个点如果右下方有点,则不可能作为答案,所以蓝线上的点为可能被选到作为答案的点

       首先先暴力求出第一个点的ans,考虑如何更新到下一个点

       

       我们发现ans的差值即为黄色部分和紫色部分的差,所以减去紫色部分再加上黄色部分即可

       加的时候横坐标单调递增,减的时候纵坐标单调递增,因为是排列所以直接计算即可,复杂度为O(n)

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int Mx=30000010;
    struct Node { int x,y; } stk[Mx];
    int n,ans,a[Mx],top;
    void pre()
    {
        int s,b,c,d;
        scanf("%d%d%d%d",&s,&b,&c,&d);
        for(int i=1;i<=n;i++)
            a[i]=i,s=(s*b+c)%d,swap(a[i],a[(s%i)+1]);
    }
    int main()
    {
        scanf("%d",&n);
        pre();
        for(int i=1;i<=n;i++)
        {
            while(a[i]<stk[top].y&&stk[top].y!=0) top--;
            stk[++top].x=i,stk[top].y=a[i];
        }
        ans=stk[1].x-1;
        for(int i=2;i<=top;i++)
            ans+=max(0,stk[i].x-stk[i-1].x-stk[i].y+stk[i-1].y);
        cout<<ans<<endl;
        return 0;
    }

       继续思考,发现一件神奇的性质:答案为max(i-a[i])

       给出证明:首先我们知道ans>=((i-1)-(a[i]=1)),即(i-a[i])为点i的ans的下界

            然后,考虑对于点i满足max(i-a[i]),我们可以知道在该点的右面不存在点j使a[j]<a[i]

            所以点i右面的点全部满足a[j]>a[i],也就是说后面比a[i]大的点有n-i个,所以前面就有i-a[i]个

            下面要证明该点在全局最大,可以尝试用数学归纳法证明

              假设前n个点(n>1)已经满足,当插入第n+1个点(值为n+1)至位置pos时,首先xpos不可能为答案

              ∀j<pos,xj不变 ; ∀pos<k<=n+1,xk+1

              对应到i-a[i]中,我们发现,所以位于pos右面的i都+1,满足性质

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int Mx=30000010;
    int n,s,b,c,d,ans,a[Mx],top;
    int main()
    {
        scanf("%d%d%d%d%d",&n,&s,&b,&c,&d);
        for(int i=1;i<=n;i++)
            a[i]=i,s=(s*b+c)%d,swap(a[i],a[(s%i)+1]),ans=max(ans,i-a[i]);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Windows Azure Cloud Service (6) Reboot and Reimage
    Windows Azure Platform Introduction (7) Windows Azure Host OS 和 Guest OS
    Nod32的内网升级方案
    32位色
    ASP.NET 2.0 的内部变化
    关于Nod的离线升级方案
    光、色、补色
    解决迅雷的“重复任务提示”
    Nod32Viewer不能取得最新的镜像包的问题
    火车头实在是太好玩了
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6490731.html
Copyright © 2011-2022 走看看