• CF1340F Nastya and CBS


    题面

    英文题面

    题意:

    题意

    (n,k,q leq 10^5)

    题解:考虑到暴力的做法是用栈模拟括号序列匹配的过程,我们尝试使用分块,将元素个数减小至(O(sqrt n))级别。

    对于每个块,我们用栈来模拟暴力匹配的过程。如果两个相邻的左右括号出现适配,那么我们称这个块是不合法的,那么所有完全包含这个区间的询问也就是不合法的。可以想象,对于一个合法的块,它匹配剩下的一定是(x)个右括号和(y)个左括号。

    那么在查询时,我们就能以一堆左/右括号为单位进行匹配了。令(pre_{i,j})表示第(i)个块的后(j)个右括号的绝对值的哈希值,(suf_{i,j})表示第(i)个块的前(j)个左括号的哈希值,然后用栈模拟匹配就行了。

    由于需要进行结构体的赋值操作,可以使用指针代替vector或普通数组做到(O(1))赋值。具体实现可以看代码。

    修改时就重构一下块。

    时间复杂度:(O((n+q)sqrt n))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define F(x,y,z) for(re x=y;x<=z;x++)
    #define FOR(x,y,z) for(re x=y;x>=z;x--)
    typedef long long ll;
    #define I inline void
    #define IN inline int
    #define C(x,y) memset(x,y,sizeof(x))
    #define STS system("pause")
    template<class D>I read(D &res){
    	res=0;register D g=1;register char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')g=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)){
    		res=(res<<3)+(res<<1)+(ch^48);
    		ch=getchar();
    	}
    	res*=g;
    }
    const int Mod=1e9+7,P=19260817,invp=494863259;
    int n,m,q,a[101000],sit,X,Y;
    int len,b[101000],S,ned[330],sn[330];
    int p[101000],inv[101000];
    int s[101000],R;vector<int>vec;
    IN Pow(int x,int y=Mod-2){
    	re res=1;
    	while(y){
    		if(y&1)res=(ll)res*x%Mod;
    		x=(ll)x*x%Mod;
    		y>>=1;
    	}
    	return res;
    }
    IN Plus(int x,int y){(x+=y)>=Mod?x-=Mod:0;return x;}
    struct Hash{
    	int *has;int len;
    	I init(int x){len=0;has=new int[x+1];has[0]=0;}
    	I insert(int x){++len;has[len]=Plus((ll)has[len-1]*P%Mod,x);}
    	IN calc(int x){if(x>len)return -1;return Plus(has[len],Mod-(ll)has[len-x]*p[x]%Mod);}
    	I delet(int x){len-=x;}
    }pre[320],suf[320],tmp;
    stack<Hash>st;
    IN gethas(){
    	re res=0;
    	for(auto d:vec)res=Plus((ll)res*P%Mod,d);
    	return res;
    }
    I get(int x){
    	if(!ned[x])return;
    	ned[x]=0;
    	static int l,r;l=(x-1)*len+1;r=min(n,x*len);
    	R=0;sn[x]=0;
    	F(i,l,r){
    		if(a[i]>0||(a[i]<0&&(!R||s[R]<0))){s[++R]=a[i];continue;}
    		if((a[i]+s[R]))return sn[x]=1,void();
    		R--;
    	}
    	vec.clear();while(R&&s[R]>0)vec.emplace_back(s[R]),R--;reverse(vec.begin(),vec.end());
    	suf[x].init(vec.size());for(auto w:vec)suf[x].insert(w);
    	pre[x].init(R);while(R&&s[R]<0)pre[x].insert(-s[R]),R--;
    }
    IN ques(int x,int y){
    	if(!((y-x)&1))return 0;
    	static int l,r;l=b[x];r=b[y];
    	if(r-l<2){
    		while(R)R--;
    		F(i,x,y){
    			if(a[i]>0){s[++R]=a[i];continue;}
    			if(!R||(a[i]+s[R]))return 0;
    			R--;
    		}
    		if(!R)return 1;
    		return 0;
    	}
    	F(i,l+1,r-1){
    		get(i);
    		if(sn[i])return 0;
    	}
    	while(R)R--;
    	F(i,x,min(n,len*l)){
    		if(a[i]>0){s[++R]=a[i];continue;}
    		if(!R||(a[i]+s[R]))return 0;
    		R--;
    	}
    	suf[0].init(R);
    	vec.clear();while(R)vec.emplace_back(s[R]),R--;reverse(vec.begin(),vec.end());
    	for(auto w:vec)suf[0].insert(w);
    	while(R)R--;
    	F(i,(r-1)*len+1,y){
    		if(a[i]>0||(a[i]<0&&(!R||s[R]<0))){s[++R]=a[i];continue;}
    		if((a[i]+s[R]))return 0;
    		R--;
    	}
    	if(R&&s[R]>0)return 0;
    	pre[0].init(R);while(R)pre[0].insert(-s[R]),R--;
    	while(!st.empty())st.pop();st.emplace(suf[0]);
    	F(i,l+1,r){
    		if(i<r)tmp=pre[i];else tmp=pre[0];
    		while(tmp.len&&!st.empty()){
    			if(st.top().len>=tmp.len){
    				if(st.top().calc(tmp.len)^tmp.calc(tmp.len))return 0;
    				st.top().delet(tmp.len);
    				if(!st.top().len)st.pop();
    				tmp.len=0;
    				break;
    			}
    			if(st.top().calc(st.top().len)^tmp.calc(st.top().len))return 0;
    			tmp.delet(st.top().len);st.pop();
    		}
    		if(tmp.len)return 0;
    		if(i==r){
    			while(!st.empty()&&!st.top().len)st.pop();
    			if(st.empty())return 1;
    			return 0;
    		}
    		st.emplace(suf[i]);
    	}
    	return 0;
    }
    int main(){
    	read(n);read(m);p[0]=1;F(i,1,n)p[i]=(ll)p[i-1]*P%Mod;inv[0]=1;F(i,1,n)inv[i]=(ll)inv[i-1]*invp%Mod;
    	F(i,1,n)read(a[i]);
    	len=ceil(sqrt(n)+0.5);F(i,1,n)b[i]=((i-1)/len)+1;S=b[n];
    	F(i,1,S)ned[i]=1;
    	read(q);
    	while(q--){
    		read(sit);read(X);read(Y);
    		if(sit==1)a[X]=Y,ned[b[X]]=1;
    		else{
    			if(ques(X,Y))cout<<"Yes"<<endl;
    			else cout<<"No"<<endl;
    		}
    	}
    	return 0;
    }
    /*
    10 10
    10 4 2 -2 1 -1 -4 8 -8 -10
    100
    1 1 4
    1 10 -4
    2 6 9
    1 3 4
    1 4 -4
    2 2 8
    2 3 4
    2 2 9
    2 3 7
    2 8 9
    2 2 4
    2 1 7
    2 3 8
    1 5 6
    1 6 -6
    2 5 6
    1 8 5
    1 9 -5
    1 3 7
    1 4 -7
    1 8 10
    1 9 -10
    1 2 8
    1 7 -8
    2 3 4
    2 4 6
    2 1 3
    1 8 1
    1 9 -1
    2 2 5
    1 1 9
    1 10 -9
    1 5 4
    1 6 -4
    1 5 4
    1 6 -4
    2 2 7
    2 8 9
    2 2 7
    2 2 7
    1 2 3
    1 7 -3
    1 3 7
    1 4 -7
    2 1 10
    */
    
  • 相关阅读:
    (转)Too many open files
    Python小程序扫描清理Redis中的key
    spring-mvc接口返回json格式数据Long类型字段精度失真
    项目基础配置
    搭建Vue脚手架(vue-cli)并创建一个项目
    项目简介
    [技术学习]HTTP 常见状态码
    git 使用beyond compare 记录
    温故知新之架构图
    学年教学总结
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/13298809.html
Copyright © 2020-2023  润新知