zoukankan      html  css  js  c++  java
  • 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:

    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.

    (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

    或者你像题解那样也行。

  • 相关阅读:
    C++笔试题库之编程、问答题 150~200道
    C++语言中的static关键字的作用是什么?
    C++开发工程师面试题库 1~50道
    C++笔试题库之编程、问答题 100~150道
    C++经典面试题库 附带参考答案
    常用的16个c/c++面试题
    C++经典面试题全集 50~100道 都附带有参考答案
    c++常见面试题30道
    别傻了,人家离职你也离
    西苑附近的一亩园社区
  • 原文地址:https://www.cnblogs.com/autoint/p/12772209.html
Copyright © 2011-2022 走看看