1473 D. Program(预处理^_^)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1473 D. Program(预处理^_^)相关的知识,希望对你有一定的参考价值。
有个显然的结论:在一段连续的 + − +- +−之后,值域的变化都是连续的
这意味着,变化的过程有个最小值和最大值,中间的所有值都是答案。
所以我们的目的是,找到删除 [ l , r ] [l,r] [l,r]后的最小值和最大值
不妨分段考虑,删掉 [ l , r ] [l,r] [l,r]后分裂为两段 [ 1 , l − 1 ] [1,l-1] [1,l−1]和 [ r + 1 , n ] [r+1,n] [r+1,n]
[ 1 , l − 1 ] [1,l-1] [1,l−1]的最大值 m x [ l − 1 ] mx[l-1] mx[l−1]最小值 [ m i [ l − 1 ] [mi[l-1] [mi[l−1]可以预处理出来,且预处理当前值为 z h i [ i ] zhi[i] zhi[i]
现在的值为 z h i [ l − 1 ] zhi[l-1] zhi[l−1],那么现在考虑 [ r + 1 , n ] [r+1,n] [r+1,n]段的影响
也就是需要预处理从点 r + 1 r+1 r+1开始的, + + +比 − - −最多的个数 f m a x [ r + 1 ] fmax[r+1] fmax[r+1]
预处理从点 r + 1 r+1 r+1开始的, − - −比 + + +最多的个数 f m i n [ r + 1 ] fmin[r+1] fmin[r+1]
倒过来做一遍最大最小连续子段和可以 O ( n ) O(n) O(n)预处理这两个数组
那么最后的最小值为
a n s m i = m i n ( m i [ l − 1 ] , z h i [ l − 1 ] + f m i [ r + 1 ] ) ansmi = min( mi[l-1],zhi[l-1]+fmi[r+1] ) ansmi=min(mi[l−1],zhi[l−1]+fmi[r+1])
最后的最大值为
a n s m x = m a x ( m x [ l − 1 ] , z h i [ l − 1 ] + f m x [ r + 1 ] ) ansmx = max(mx[l-1], zhi[l-1]+fmx[r+1] ) ansmx=max(mx[l−1],zhi[l−1]+fmx[r+1])
于是可以 O ( 1 ) O(1) O(1)知道答案
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int n,m,mi[maxn],mx[maxn],zhi[maxn],fmi[maxn],fmx[maxn];
char a[maxn];
int main()
int t; cin >> t;
while( t-- )
cin >> n >> m;
for(int i=1;i<=n;i++)
cin >> a[i];
if( a[i]=='-' ) zhi[i]=zhi[i-1]-1;
else zhi[i]=zhi[i-1]+1;
mi[i] = min( mi[i-1],zhi[i] );
mx[i] = max( mx[i-1],zhi[i] );
fmi[n+1]=fmx[n+1]=0;
for(int i=n;i>=1;i--)
if( a[i]=='-' )
fmi[i] = min( -1,fmi[i+1]-1 );
fmx[i] = max( -1,fmx[i+1]-1 );
else
fmi[i] = min( 1,fmi[i+1]+1 );
fmx[i] = max( 1,fmx[i+1]+1 );
for(int i=1;i<=m;i++)
int l,r; scanf("%d%d",&l,&r);
int ansmi = 0,ansmx = 0;
ansmi = min( zhi[l-1]+fmi[r+1],mi[l-1] );
ansmx = max( zhi[l-1]+fmx[r+1],mx[l-1] );
printf("%d\\n",ansmx-ansmi+1);
以上是关于1473 D. Program(预处理^_^)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Gym 101138 D. Strange Queries
Codeforces Round #729 (Div. 2) D. Priority Queue(简单dp)