码迷,mamicode.com
首页 > 其他好文 > 详细

CF1340F Nastya and CBS

时间:2020-04-25 12:38:47      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:class   sub   ash   air   lan   osi   pair   维护   pre   

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:

  1. Replace the bracket at position \(i\) with the bracket of the form \(t\).

  2. Check if the substring from the \(l\)-th to \(r\)-th position (including) is the correct bracket sequence.

\(1\leq n,q\leq 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(n\log^2 n)\)https://codeforces.ml/contest/1340/submission/77902949

或者你像题解那样也行。技术图片

CF1340F Nastya and CBS

标签:class   sub   ash   air   lan   osi   pair   维护   pre   

原文地址:https://www.cnblogs.com/autoint/p/12772209.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!