JZOJ7月24日提高组T2 圣章-精灵使的魔法语

JZOJ7月24日提高组T2 圣章-精灵使的魔法语

  • 题目
  • 题解
    • 题意
    • 分析
    • Code

题目

【背景介绍】
“魔法???算了吧,这种东西我肯定学不了的啦!”明明是个剑士,却被眼前这位洋洋自得的精灵使——弗洛莉拖出去学魔法,真是个没事找茬的家伙……
“没事啦。作为一名冒险者会发生很多情况,中毒啦,受伤啦,被咒语束缚之类的,没有魔法就很难办的呀!”她到是好像一副什么都懂的样子,真是令人火大。
“都说我是个人类了,魔法这种东西学起来很困难的吧!”我只好找个看似靠谱的借口。
然而,她那不屈不挠的声音又响了起来:“人类虽然与自然的共鸣,也就是魔法的连接较少,但如果认真训练的话还是可以做到的呢!总之,试试看吧!念念咒语之类的!”弗洛莉把魔法书一把拍在了我面前。
我没兴趣地瞟了一眼,“哼。这种东西我不看也会,伦福萨——密西卡!”才刚刚念完不知道从哪里偷学来的魔法咒语。随即,便听到弗洛莉的一声尖叫,使得整个酒店的人的视线都往这边看来。喂喂喂,别往我这边看啊,我有视线恐惧症啊!!!!况且,我只是把她正在吃的面包的样子变成虫子而已,谁会料到这种情况啊啊啊!!
“真是的,弗洛莉才是老拖我的后腿呢!”我没好气地笑道……
“里修!你……”她从牙缝里挤出了一个字。我顿感不妙,见到了那张比魔鬼还可怕的扭曲的面孔。“真是个魔法的天才哪!”她一扫之前不愉快的表情,想我露出大拇指,好像是在夸奖我的样子。
咦?她竟然没有打我,那真是我福大命大。我这样想着,便一屁股坐在了凳子上,松了口气……
【题目描述】
“伦福萨”【即" ( “】和“密西卡”【即” ) “】是两种不同的精灵咒语,已知一个成功的咒语符合如下的规定:
每一个密西卡之前都可以对应匹配到一个伦福萨,即为一个合法的精灵魔法咒语。
方便的是,我们将“伦福萨”视为” ( “,“密西卡”视为” ) “,合法的精灵魔法咒语即为一个合法的括号序列。
如:” ( ( ( ) ) ) “” ( ( ) ( ) ) “” ( ) ( ) ( ) “均为合法的魔法咒语,” ) ( “” ( ) ) ( “” ( ( “均为不合法的魔法咒语。
现在弗洛莉给我一个长长的“伦福萨”【即” ( “】和“密西卡”【即” ) “】的片段,每次给我一个l和r,让我判断需要在这个片段前最少添多少个“伦福萨”【即” ( “】,以及最少添多少个“密西卡”【即” ) “】可以成为一个合法的魔法咒语,更令人不爽的是,弗洛莉有的时候还会把一个“伦福萨”【即” ( “】变成“密西卡”【即” ) “】,或把一个“密西卡”【即” ) “】变为“伦福萨”【即” ( "】。

题解

题意

冗长又中二题目描述
有一个括号序列,有两种操作:更改和查询
更改是将一个括号由左括号变成右括号,右括号变成左括号
查询是查询一个区间内有多少个不合法的左括号和右括号

分析

看到更改查询,马上想到线段树
那么就可以转换成一个单点修改,区间查询的线段树
线段树维护两个值,分别是当前区间内不合法的左括号和右括号的数量
对于线段树的转移
思考左括号
容易想到,在右儿子中多出来的左括号是没有右括号进行匹配的
另外,左儿子中的左括号会和右儿子中的右括号进行匹配,所以要加上左儿子中的左括号和右儿子中的右括号的差
注意,当左儿子中的左括号不够右儿子中的右括号时,加上的是0不是差(可以将差和0取个 m a x max max
公式: t r e e [ 当 前 节 点 ] [ 左 ] = t r e e [ 右 儿 子 ] [ 左 ] + m a x ( t r e e [ 左 儿 子 ] [ 左 ] − t r e e [ 右 儿 子 ] [ 右 ] , 0 ) tree[当前节点][左]=tree[右儿子][左]+max(tree[左儿子][左]-tree[右儿子][右],0) tree[][]=tree[][]+max(tree[][]tree[][],0)
思考右括号
同理,在左儿子中多出来的右括号是没有左括号进行匹配的
并且右儿子中的右括号会和左儿子中的左扩号进行匹配,所以要加上右儿子中的右括号和左儿子中的左括号的差
当右儿子中的右括号不够左儿子中的左括号时,加上的是0不是差(方法同上)
公式: t r e e [ 当 前 节 点 ] [ 右 ] = t r e e [ 左 儿 子 ] [ 右 ] + m a x ( t r e e [ 右 儿 子 ] [ 右 ] − t r e e [ 左 儿 子 ] [ 左 ] , 0 ) tree[当前节点][右]=tree[左儿子][右]+max(tree[右儿子][右]-tree[左儿子][左],0) tree[][]=tree[][]+max(tree[][]tree[][],0)
告知:“左”指左括号,“右”指右括号
线段树维护即可
求答案跟维护是一样的
小心字符串读入时间

Code

#include
#include
using namespace std;
int n,m,i,x,y,len,ans1,ans2,tree[600005][3];
char s[150005],c,ch[10];
bool b;
void biuld(int now,int l,int r)//建树
{
	int mid;
	if (l==r)
	{
		if (s[l-1]=='(') tree[now][1]=1;
		else tree[now][2]=1;
		return;
	}
	mid=(l+r)>>1;
	biuld(now*2,l,mid);
	biuld(now*2+1,mid+1,r);
	tree[now][1]=tree[now*2+1][1]+max(tree[now*2][1]-tree[now*2+1][2],0);
	tree[now][2]=tree[now*2][2]+max(tree[now*2+1][2]-tree[now*2][1],0);
}
int query(int now,int l,int r,int p,int q,int bj)//查询
{
	int mid;
	if (l>q) return 0;
	if (r<p) return 0;
	if (l==p&&r==q) return tree[now][bj];
	mid=(l+r)>>1;
	if (q<=mid) return query(now*2,l,mid,p,q,bj);
	else if (p>mid) return query(now*2+1,mid+1,r,p,q,bj);
	else 
	{
		if (bj==1) return (query(now*2+1,mid+1,r,mid+1,q,1)+max(query(now*2,l,mid,p,mid,1)-query(now*2+1,mid+1,r,mid+1,q,2),0));
		else return (query(now*2,l,mid,p,mid,2)+max(query(now*2+1,mid+1,r,mid+1,q,2)-query(now*2,l,mid,p,mid,1),0));
	}
}
void modify(int now,int l,int r,int p)//修改
{
	int mid;
	if (l>p) return;
	if (r<p) return;
	if (l==r)
	{
		tree[now][1]=1-tree[now][1];
		tree[now][2]=1-tree[now][2];
		return;
	}
	mid=(l+r)>>1;
	modify(now*2,l,mid,p);
	modify(now*2+1,mid+1,r,p);
	tree[now][1]=tree[now*2+1][1]+max(tree[now*2][1]-tree[now*2+1][2],0);
	tree[now][2]=tree[now*2][2]+max(tree[now*2+1][2]-tree[now*2][1],0);
}
int main()
{
	freopen("elf.in","r",stdin);
	freopen("elf.out","w",stdout);
	scanf("%d%d",&n,&m);
	c=getchar();//读入
	while (c!='('&&c!=')') c=getchar();
	while (c=='('||c==')')
	{
		s[len]=c;
		len++;
		c=getchar();
	}
	biuld(1,1,n);
	for (i=1;i<=m;i++)
	{
		b=false;
		c=getchar();//读入
		while (c!='Q'&&c!='C') c=getchar();
		if (c=='Q') b=true;
		while((c>='a'&&c<='z')||(c>='A'&&c<='Z')) c=getchar();
		if (b==true)
		{
			ans1=0;
			ans2=0;
			scanf("%d%d",&x,&y);
			ans2=query(1,1,n,x,y,1);
			ans1=query(1,1,n,x,y,2);
			printf("%d %d\n",ans1,ans2);
		}
		else
		{
			scanf("%d",&x);
			modify(1,1,n,x);
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}

你可能感兴趣的:(信息学总结)