CF1340F Nastya and CBS
Posted autoint
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1340F Nastya and CBS相关的知识,希望对你有一定的参考价值。
Nastya and CBS
A string (s) is given. It consists of (k) kinds of pairs of brackets. Each bracket has the form (t) — it is an integer, such that (1 leq |t| leq k). If the bracket has a form (t), then:
-
If (t > 0), then it‘s an opening bracket of the type (t).
-
If (t < 0), then it‘s a closing bracket of the type (-t).
Thus, there are (k) types of pairs of brackets in total.
The queries need to be answered:
-
Replace the bracket at position (i) with the bracket of the form (t).
-
Check if the substring from the (l)-th to (r)-th position (including) is the correct bracket sequence.
(1leq n,qleq 10^5).
题解
考虑维护区间前缀未匹配上的右括号和后缀未匹配上的左括号。
合并区间的时候把左边区间的后缀右括号和右边区间的前缀左括号抵消掉即可。
考虑分块,然后(O(qn))过(10^5)。因为memcpy
常数很小,所以即使是(10^5)个左括号复制(10^5)次,还是能跑出来。
CO int N=1e5+10,M=320;
int seq[N],lab[N];
int L[M],R[M],ok[M];
int F[M][N],G[M][N];
void build(int x){
ok[x]=1,F[x][0]=G[x][0]=0;
static int stk[N];
int top=0;
for(int i=L[x];i<=R[x];++i){
if(seq[i]>0) stk[++top]=seq[i];
else if(top){
if(stk[top]!=-seq[i]){
ok[x]=0; return;
}
--top;
}
else F[x][++F[x][0]]=seq[i];
}
memcpy(G[x]+1,stk+1,sizeof(int)*top),G[x][0]=top;
}
bool query(int l,int r){
static int stk[N];
int top=0;
if(lab[l]==lab[r]){
for(int i=l;i<=r;++i){
if(seq[i]>0) stk[++top]=seq[i];
else{
if(!top or stk[top]!=-seq[i]) return 0;
--top;
}
}
return !top;
}
for(int i=l;i<=R[lab[l]];++i){
if(seq[i]>0) stk[++top]=seq[i];
else{
if(!top or stk[top]!=-seq[i]) return 0;
--top;
}
}
for(int x=lab[l]+1;x<=lab[r]-1;++x)if(!ok[x]) return 0;
for(int x=lab[l]+1;x<=lab[r]-1;++x){
if(top<F[x][0]) return 0;
for(int i=1;i<=F[x][0];++i){
if(stk[top]!=-F[x][i]) return 0;
--top;
}
memcpy(stk+top+1,G[x]+1,sizeof(int)*G[x][0]),top+=G[x][0];
}
for(int i=L[lab[r]];i<=r;++i){
if(seq[i]>0) stk[++top]=seq[i];
else{
if(!top or stk[top]!=-seq[i]) return 0;
--top;
}
}
return !top;
}
int main(){
int n=read<int>(),k=read<int>();
for(int i=1;i<=n;++i) read(seq[i]);
int m=ceil(pow(n,0.55));
for(int i=1;i<=n;++i) lab[i]=(i+m-1)/m;
for(int i=1;i<=lab[n];++i) L[i]=R[i-1]+1,R[i]=min(i*m,n);
for(int i=1;i<=lab[n];++i) build(i);
for(int q=read<int>();q--;){
if(read<int>()==1){
int i=read<int>();
read(seq[i]),build(lab[i]);
}
else{
int l=read<int>(),r=read<int>();
puts(query(l,r)?"Yes":"No");
}
}
return 0;
}
正确的做法是在线段树上维护这些括号序列的hash值,抵消的时候递归长度大的一侧查询对应长度的hash值。
时间复杂度(O(nlog^2 n))。https://codeforces.ml/contest/1340/submission/77902949
或者你像题解那样也行。
以上是关于CF1340F Nastya and CBS的主要内容,如果未能解决你的问题,请参考以下文章
CF1340D Nastya and Time Machine
CF1340D Nastya and Time Machine