[BZOJ 2086]Poi 2010 Blocks

来源:互联网 发布:mac nginx lua 安装 编辑:程序博客网 时间:2024/05/29 08:58

实战的时候逗比的使劲儿优化O(mnlgn)的算法,搞得吐血后才多对1个点,还是有2个点毫无压力的T啦敲打

然后看了题解才发现自己逗比到一定境界了。。。。

我们的目的就是找到最小的j,使得j<i且s[j]<s[i]。只分析到这是不够的,因为我们不是要求每一个i对应的j,只要求出最大的j-i。

这样我们就可以去掉lgn了。把s最成一个单调下降的序列,现在队列求出n对应的j(很明显j存在于这个下降序列中),我们发现在找n-1对应的j中,若想更新答案,其对应的j必定比n对应的j小!

因此我们只用两个指针不停地移动就行了。复杂度O(nm)

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int Maxn=1000005;int n,m,i,j,ans,l,r,mid,t,k,a[Maxn],q[Maxn];LL s[Maxn];int read(){  char ch=getchar();  int ret=0;  while (ch<'0'||ch>'9')ch=getchar();  while (ch>='0'&&ch<='9')    {ret=ret*10+ch-'0';ch=getchar();}  return ret;}int main(){  n=read(); m=read();  for (i=1;i<=n;i++)    a[i]=read();  while (m--){  k=read();    for (i=1,ans=0,t=0;i<=n;i++){    s[i]=s[i-1]+(LL)a[i]-k;    if (s[q[t]]>s[i]) q[++t]=i;    }    for (i=n,j=t;j>=0&&i>=0;i--){      while (j>=0 &&  s[i]>=s[q[j]]) j--;      j++;      ans=max(ans,i-q[j]);    }    printf("%d",ans);    if (m) printf(" "); else printf("\n");  }  return 0;}


0 0
原创粉丝点击