稳定的子串

单调队列 维护2*j-b[j] b[j]:从j开始能够伸长到哪里

/*
    单调队列 
*/
#include<iostream>
#include<cstdio>
using namespace std;
int n,s,head=0,tail=-1;
int a[100010],b[100010],q[200010],ans[100010];
void push(int j)
{
    int k=2*j-b[j];
    while(head<=tail)
    {
        if(2*q[tail]-b[q[tail]]>=k)tail--;
            else break;
    }
    tail++;
    q[tail]=j;
}
int main()
{
    cin>>n>>s;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int j=1,tot=0;
    for(int i=1;i<=n;i++)
    {
        tot-=a[i-1];
        while(tot+a[j]<=s&&j<=n){
          tot+=a[j];
          j++;
        }        
        b[i]=j;
    }
    for(int i=1;i<=n;i++) cout<<b[i]<<" ";
    cout<<endl;
    int f=1;
    for(int i=1;i<=n;i++)
    {
        for(;f<=b[i];f++)
        {
            push(f);
        }
        while(i>q[head]) head++; 
        //if(2*q[head]-b[q[head]+1]+1>i) continue;        
        while(head<tail)
        {
            int k=q[head+1];
            if(2*k-b[k]>i) break;
            head++;
        }
        ans[i]=2*q[head]-2*i; 
    }
    for(int i=1;i<=n;i++)
        printf("%d\n",ans[i]);
    return 0;
}

 

posted @ 2016-10-15 22:19  19992147  阅读(134)  评论(0编辑  收藏  举报