首页 > 其他分享 >CF1340F Nastya and CBS

CF1340F Nastya and CBS

时间:2024-01-19 16:55:22浏览次数:20  
标签:le ln nd1 nd CBS CF1340F Nastya nd2 rn

更好的阅读体验

CF1340F Nastya and CBS

绷不住了,30min 写完,虚空调试 2h+/lh/lh。

如果要准确做的话太困难了,考虑 hash。多次区间询问,考虑线段树。

一个区间如果内部合法,把内部能匹配的都匹配上,一定是左边一段右括号加上右边一段左括号。节点需要记录左边长度,右边长度和左右分别的 hash 值。

合并的时候,如果左儿子和右儿子有内部不合法的情况当前节点直接不合法。

另一种不合法的情况是左儿子的后缀和右儿子的前缀如果出现不能匹配的那这个区间就不合法。这个东西可以类似单侧递归线段树实现,线段树上二分查询左儿子一段后缀的 hash 或者右儿子一段前缀的 hash 与另外一个儿子的 hash 比较,若不相等则一定不合法,复杂度是 \(\mathcal O(\log^2n)\)。

比较左儿子后缀和右儿子的前缀长度。如果前者大于后者,则把左儿子的后缀的一段前缀拼上右儿子的全部后缀作为当前节点的后缀,反之亦然。

细节比较多,注意就算区间不合法也需要维护前后缀不匹配括号的长度,因为需要线段树上二分。模数卡 \(998244353\),可以用 \(10^9+7\)。

代码写的比较丑,见谅/wul。

	int n,m,K,a[100010],fr[100010];
	namespace Segment
	{
		struct Node{int l,r,le,ri,ln,rn,fl;}t[400010],NUL;
		Node mul(Node nd1,Node nd2,int id)
		{
			Node nd;nd=NUL,nd.l=nd1.l,nd.r=nd2.r,nd.fl=0;
			if(nd1.fl||nd2.fl)return nd.fl=1,nd;
			if(nd1.rn>nd2.ln)
			{
				nd.le=nd1.le,nd.ln=nd1.ln;
				nd.rn=nd1.rn-nd2.ln+nd2.rn;
				nd.ri=Cmul(nd2.ri,fr[nd1.rn-nd2.ln]);
				Madd(nd.ri,Cdel(nd1.ri,Cmul(nd2.le,fr[nd1.rn-nd2.ln])));
			}
			else
			{
				nd.ri=nd2.ri,nd.rn=nd2.rn;
				nd.ln=nd1.ln+nd2.ln-nd1.rn;
				nd.le=Cmul(nd1.le,fr[nd2.ln-nd1.rn]);
				Madd(nd.le,Cdel(nd2.le,Cmul(nd1.ri,fr[nd2.ln-nd1.rn])));
			}
			return nd;
		}
		Node queryr(int p,int k)
		{
			if(!k)return NUL;
			if(t[p].l==t[p].r)return t[p];
			if(t[p*2+1].rn>=k)return queryr(p*2+1,k);
			return mul(queryr(p*2,k-t[p*2+1].rn+t[p*2+1].ln),t[p*2+1],p);
		}
		Node queryl(int p,int k)
		{
			if(!k)return NUL;
			if(t[p].l==t[p].r)return t[p];
			if(t[p*2].ln>=k)return queryl(p*2,k);
			return mul(t[p*2],queryl(p*2+1,k-t[p*2].ln+t[p*2].rn),p);
		}
		Node add(Node nd1,Node nd2,int id)
		{
			Node nd;nd=NUL,nd.l=nd1.l,nd.r=nd2.r,nd.fl=0;
			nd.ln=nd1.ln+max(nd2.ln-nd1.rn,0);
			nd.rn=nd2.rn+max(nd1.rn-nd2.ln,0);
			if(nd1.fl||nd2.fl)
			return nd.fl=1,nd;
			if(nd1.rn>nd2.ln)
			{
				if(queryr(id*2,nd2.ln).ri!=nd2.le)return nd.fl=1,nd;
				nd.le=nd1.le,nd.ri=Cmul(nd2.ri,fr[nd1.rn-nd2.ln]);
				Madd(nd.ri,Cdel(nd1.ri,Cmul(nd2.le,fr[nd1.rn-nd2.ln])));
			}
			else
			{
				if(queryl(id*2+1,nd1.rn).le!=nd1.ri)return nd.fl=1,nd;
				nd.ri=nd2.ri,nd.le=Cmul(nd1.le,fr[nd2.ln-nd1.rn]);
				Madd(nd.le,Cdel(nd2.le,Cmul(nd1.ri,fr[nd2.ln-nd1.rn])));
			}
			return nd;
		}
		void build(int p,int l,int r)
		{
			t[p].l=l,t[p].r=r;
			if(l==r)
			{
				if(a[l]<0)t[p].ln=1,t[p].rn=t[p].ri=0,t[p].le=-a[l];
				else t[p].rn=1,t[p].ln=t[p].le=0,t[p].ri=a[l];
				return;
			}
			int mid=l+((r-l)>>1);
			build(p*2,l,mid),build(p*2+1,mid+1,r);
			t[p]=add(t[p*2],t[p*2+1],p);
		}
		void change(int p,int x,int y)
		{
			if(t[p].l==t[p].r)
			{
				if(y<0)t[p].ln=1,t[p].rn=t[p].ri=0,t[p].le=-y;
				else t[p].rn=1,t[p].ln=t[p].le=0,t[p].ri=y;
				return;
			}
			x<=t[p*2].r?change(p*2,x,y):change(p*2+1,x,y);
			t[p]=add(t[p*2],t[p*2+1],p);
		}
		Node ask(int p,int l,int r)
		{
			if(l<=t[p].l&&r>=t[p].r)return t[p];
			if(r<=t[p*2].r)return ask(p*2,l,r);
			if(l>t[p*2].r)return ask(p*2+1,l,r);
			Node lef=ask(p*2,l,r);
//			assert(lef.fl||lef.rn<=t[p*2].rn);
			Node rig=ask(p*2+1,l,r);
//			assert(rig.fl||rig.ln<=t[p*2+1].ln);
			return add(lef,rig,p);
		}
		void print(int p)
		{
			write('(',t[p].l,',',t[p].r,')',t[p].fl,' ',t[p].le,' ',t[p].ln,' ',t[p].ri,' ',t[p].rn,'\n');
			if(t[p].l==t[p].r)return;
			print(p*2),print(p*2+1);
		}
	}
	using namespace Segment;
	inline void mian()
	{
		read(n,K),fr[0]=1,NUL={0,0,0,0,0,0,0};int opt,x,y;
		for(int i=1;i<=n;++i)read(a[i]),fr[i]=Cmul(fr[i-1],131);
		build(1,1,n),read(m);int M=m;
		while(m--)
		{
//			cerr<<M-m<<endl;
			read(opt,x,y);
			if(opt==1)change(1,x,y);
			else
			{
				Node nd=ask(1,x,y);
				if(!nd.ln&&!nd.rn&&!nd.le&&!nd.ri&&!nd.fl)puts("Yes");
				else puts("No");
			}
		}
	}

标签:le,ln,nd1,nd,CBS,CF1340F,Nastya,nd2,rn
From: https://www.cnblogs.com/WrongAnswer90-home/p/17975061

相关文章

  • CF992E Nastya and King-Shamans
    题意给定一个序列\(s\),记其前缀和序列为\(g_i\),\(q\)次修改。每次修改后输出任意满足\(s_i=g_{i-1}\)的解。Sol前缀和数组,每次答案使\(s_i\times2\)。也就是答案的个数不会超过\(log\)。再想,\(s_i-g_{i-1}\ge0\)的个数也不会超过\(log\)。于是我们考......
  • Codeforces Round 637 (Div. 2) - Thanks, Ivan Belonogov! A. Nastya and Rice
    纳斯塔亚掉了\(n\)个谷物,每个谷物的重量范围在\([a-b,a+b]\)。她猜测谷物的总重量范围在\([c-d,c+d]\)。询问她的猜测是否正确。显然,若\([n(a-b),n(a+b)]\)和\([c-d,c+d]\)有交,则她的猜测正确。view#include<bits/stdc++.h>typedeflonglongll;......
  • E. Nastya and Potions
    E.NastyaandPotions思路:直接对比制造这份药剂和直接买那个更好判断特殊:1.如果已经拥有就不用再买了2.如果只能买,就直接买方法:1.dfs,因为要制造3,可能先要制造1,这样我们就dfs把条件从叶子节点全都往上传就行优化:1.如果之前已经知道了制造的价格,那么直接返回就行注意点:1.......
  • 10基于构件的软件工程CBSE
    CBSE强调的是使用购买而来的构件,而不是重新建造。CBSE构件的特征是: 可组装性:通过公共接口交互,接口公开化,使得构件可以通过接口组装。可部署性:构件要求是二进制的形式,可以独立运行在平台之上文档化:构件有文件的记录供参考独立性:构件可以自行组装而不需要依赖特殊的环境标准......
  • B. Nastya Studies Informatics
    B.NastyaStudiesInformaticstimelimitpertest1secondmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputTodayonInformaticsclassNastyalearnedaboutGCDandLCM(seelinksbelow).Nastyaisveryintelligent,soshesolvedall......
  • CBS拒绝与Apple TV的流媒体合作
    美国最大电视台CBS几个小时前刚刚发布季度财报,CEOLesMoonves又爆出了一条消息:因在广告收入分成方面存在分歧,CBS拒绝了苹果的流媒体合作协议。很久以前就有传言称苹果......
  • 记录一次win10修复|System Failed to Initialize In Windows|CBSLog
    起因:系统初始化失败,尝试使用如下命令行修复sfc/SCANNOW生成CBS日志,可以搜索关键字“Couldnot”定位到问题行关闭联想锁屏后解决cmd问题最终退出杀软后成功安装参......
  • CF992E Nastya and King-Shamans 题解
    传送门分析由于满足\(a_i\ge0\),所以\(s_i\)单调不减。当我们找到一个\(i\)时,不管\(i\)是否满足,下一个可能的一定大于等于\(a_i+s_{i-1}\)。而且\(a_i+s_{i-1}......
  • IfcBSplineSurfaceForm
    IfcBSplineSurfaceForm类型定义IfcBSplineSurfaceForm表示某个特定形状的曲面的一部分。 注:定义符合ISO/CD10303-42:1992此类型用于指示B样条曲线曲面表示某种特定......
  • IfcBSplineCurveForm
    IfcBSplineCurveForm类型定义IfcBSplineCurveForm表示某些特定形式的曲线的一部分。 注:定义符合ISO/CD10303-42:1992此类型用于指示B样条曲线代表某种特定形式的曲......