稳定的子串

单调队列 维护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;
}
时间: 2024-08-07 16:41:31

稳定的子串的相关文章

Java 最长子序列和最长子串

最长子序列:匹配的字符不需要连续. 最长子串: 匹配的字符需要连续,可能有多种结果. 解决思路:将输入字符串1看作行, 输入字符串2看作列,构成二位数组,然后将对角线匹配字符的值标记为1,计算满足条件的匹配字符个数即可. 基本思想: 空间换时间,动态规划. 图解与公式(只针对最长子序列,最长子串类似) 状态转移方程 直观版: 最长子序列 1 /** 2 * find longest common sequence from two input string 3 * @param s1 4 * @

BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一种稳定的暴力算法.可以想到这样一种做法:首先确定一个串,枚举每个位置,然后暴力计算其他每个串以这个位置开头的最长匹配,取最小值,就是在公共子串在我们确定下来的串的这个位置开头的时候所能得到的最长公共子串.不难发现把这个问题转化成后缀的形式也是一样的.同时发现可能在枚举多个位置的时候答案甚至最后构造出来的串都是

稳定的和不稳定的排序

https://zh.wikipedia.org/wiki/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95 ; 首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同.在简单形式化一下,如果Ai = Aj,Ai原来在位置前,排序后Ai还是要在Aj位置前. 其次,说一下稳定性的好处.排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用.基数排序

LeetCode 30 Substring with Concatenation of All Words(与所有文字串联子串)(*)

翻译 给定一个字符串S,一个单词的列表words,全是相同的长度. 找到的子串(多个)以s即每个词的字串联恰好一次并没有任何插入的字符所有的起始索引. 原文 You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word

在win10 LTSB版本中使用UWF组件,实现影子保护功能,提供稳定,高速的开发环境

Win10 LTSB,比win8好用,又没有APP功能,老机运行非常稳定.流畅.安装运行一段时间后,安装了UWF组件,提高安全性和流畅性. Windows UWF(统一写保护)组件,功能: 1.当内存盘用,加强性能,提高速度: 2.省SSD写入: 3.当还原卡用,防熊孩子 开启方法: 1.程序和功能→启用或关闭Windows功能,勾选"统一写入筛选器" 2.UWF设置 手动启动及设定 (要重新启动系统才生效,关机再开是没用的) : 用管理员模式打开控制台,挑选下列可使用命令行 uwfm

最长公共子串

(连续) - 阿里笔试[分析+编码] 题目描述:给定一个query和一个text,均由小写字母组成.要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度.例如,query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3.请注意程序效率. [思路]用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0.然后求出对角线最长的1序列,其对应的位置

HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s. And you have some query,each time you should calculate f(s[l...r]), s[l

c之PAT刷题---删除字符串中的特定子串

改了好久还是没有全过,等明天再看吧!好好休息,明天继续. #include<stdio.h> #include<string.h> char *delete(char str1[80],char str2[80]){ int len1,len2,l;//l记录出现字符相同的起始位置 len1=strlen(str1); len2=strlen(str2); for(int i=0;str1[i]!='\0';i++){ if(str1[i]==str2[0]){ l=i;//记下相

寻找最大子串

题目:从一个数组中寻找一个连续子数组,使其中元素之和最大,给出该和值. 例如:数组[-2, 1, -3, 4, -1, 2, 1, -5, 4]和最大的子串是[4, -1, 2, 1],其和为6. 分析: 将数组从中间切分,中间元素属于左边,则最大子串为下面三种情况之一: 子串仅包含左边元素: 子串仅包含右边元素: 子串同时包含左边和右边的元素: 代码: // JavaScript solution function findMaxSubArray(a, begin, end) {   if(b