首页 > 其他分享 >AtCoder-abc350_f 题解

AtCoder-abc350_f 题解

时间:2024-04-29 21:01:40浏览次数:27  
标签:node AtCoder rs int 题解 void fa abc350 ls

原题链接

题意简述

给定一个字符串 \(S\),对于每个匹配的括号,将括号内的字符左右翻转并大小写反转,然后删除括号。输出最后的序列。

思路

本题为文艺平衡树的模板题。扫一遍字符串进行括号匹配,每次把最内层的括号进行操作。最后遍历一遍平衡树,将不为括号字符的字符输出。

FHQ_Treap 的常数太大,这里使用 Splay。

代码

#include<bits/stdc++.h>
#define UP(i,a,b) for(i=a;i<=(b);++i)
#define DN(i,a,b) for(i=a;i>=(b);--i)
#define up(i,a,b) for(i=a;i<(b);++i)
#define dn(i,a,b) for(i=a;i>(b);--i)
#define pa make_pair
typedef long long ll;
using namespace std;
void rdc(char &c){for(c=getchar();c==' '||c=='\r'||c=='\n';c=getchar());}

const int N=5e5+5;
char a[N];
int len,sta[N],*top;
/*sta和top用来括号匹配*/
struct node{
	bool lz,ch;
	/*lz为Lazy-Tag,ch为最后是否反转大小写*/
	int sz,vl;
	node *ls,*rs,*fa;
}t[N],*root,*tot;

void init_node(node *u,char c){
	u->lz=u->ch=false;
	u->sz=1;
	u->vl=c;
	u->ls=u->rs=u->fa=t;
}
void push_up(node *u){
	u->sz=u->ls->sz+u->rs->sz+1;
}
void tag(node *u){
	/*给子树打Lazy-Tag*/
	if(u!=t){
		swap(u->ls,u->rs);
		u->ch^=true;
		u->lz^=true;
	}
}
void push_down(node *u){
	/*下传标记*/
	if(u->lz){
		tag(u->ls);
		tag(u->rs);
		u->lz=false;
	}
}
bool ls(node *u){
	return u->fa->ls==u;
}
void rtt(node *u){
	/*Splay旋转*/
	node *f=u->fa,*g=f->fa;
	if(ls(u)){
		f->ls=u->rs;
		if(f->ls!=t){
			f->ls->fa=f;
		}
		u->rs=f;
	}else{
		f->rs=u->ls;
		if(f->rs!=t){
			f->rs->fa=f;
		}
		u->ls=f;
	}
	if(g!=t){
		ls(f)?g->ls=u:g->rs=u;
	}else{
		root=u;
	}
	f->fa=u;u->fa=g;
	push_up(f);push_up(u);
}
void splay(node *u,node *p){
	node *f,*g;
	while(u->fa!=p){
		f=u->fa;g=f->fa;
		if(g!=p){
			rtt(ls(u)^ls(f)?u:f);
		}
		rtt(u);
	}
}
node* fd(int k){
	node *u=root;
	/*找结点时要下传标记*/
	push_down(u);
	while(u->ls->sz+1!=k){
		if(k<u->ls->sz+1){
			u=u->ls;
		}else{
			k-=u->ls->sz+1;
			u=u->rs;
		}
		push_down(u);
	}
	return u;
}
node* build(node *f,int l,int r){
	/*对字符串的[l,r]建树,返回树根*/
	if(l>r){
		return t;
	}
	int mid=(l+r)>>1;
	node *u=++tot;
	init_node(u,a[mid]);
	u->fa=f;
	u->ls=build(u,l,mid-1);
	u->rs=build(u,mid+1,r);
	push_up(u);
	return u;
}
void rev(int l,int r){
	/*翻转并反转区间[l,r]*/
	node *x=fd(l),*y=fd(r+2);
	splay(x,t);
	splay(y,x);
	tag(y->ls);
}
void tra(node *u=root){
	/*遍历平衡树*/
	if(u!=t){
		push_down(u);
		tra(u->ls);
		if(u->vl!='('&&u->vl!=')'){
			/*不是括号时就输出*/
			if(u->ch){
				if(u->vl>='a'&&u->vl<='z'){
					u->vl-=32;
				}else{
					u->vl+=32;
				}
			}
			printf("%c",u->vl);
		}
		tra(u->rs);
	}
	if(u==root){
		printf("\n");
	}
}
void init(){
	init_node(t,'(');t->sz=0;
	init_node(t+1,'(');t[1].rs=t+2;t[1].sz=2;
	init_node(t+2,'(');t[2].fa=t+1;
	/*都初始化为'(',这样在遍历的时候就不输出多余字符了*/
	root=t+1;tot=t+2;top=sta;
}
int main(){
	int i;
	scanf("%s",a+1);
	len=strlen(a+1);
	init();
	t[2].ls=build(t+2,1,len);
	push_up(t+2);push_up(t+1);
	UP(i,1,len){
		if(a[i]=='('){
			++top;*top=i;
		}else if(a[i]==')'){
			/*括号匹配成功,进行翻转*/
			rev(*top,i);
			--top;
		}
	}
	tra();
	return 0;
}

标签:node,AtCoder,rs,int,题解,void,fa,abc350,ls
From: https://www.cnblogs.com/lrxmg139/p/18166640

相关文章

  • 【题解】 量化交易1
    题目描述applepi训练了一个可以自动在股票市场进行量化交易的模型。通常来说,applepi写出的模型,你懂得,就好比一架印钞机。不过为了谨慎起见,applepi还是想先检查一下模型的效果。applpie收集了“塞帕思股份(surpass)”在最近的连续N天内的价格。在每一天中,他可以做如下事情之一:......
  • 【题解】 量化交易2
    题目描述applepi训练了一个可以自动在股票市场进行量化交易的模型。通常来说,applepi写出的模型,你懂得,就好比一架印钞机。不过为了谨慎起见,applepi还是想先检查一下模型的效果。applpie收集了“塞帕思股份(surpass)”在最近的连续N天内的价格。在每一天中,他可以做如下事情之一:......
  • 问题解决:Failed to download metadata for repo ‘appstream‘: Cannot prepare inter
    大家都知道Centos8于2021年年底停止了服务,大家再在使用yum源安装时候,出现下面错误“错误:Failedtodownloadmetadataforrepo‘AppStream’:Cannotprepareinternalmirrorlist:NoURLsinmirrorlist”1、进入yum的repos目录代码语言:javascript复制cd/etc/yum......
  • git - git 问题解决方案汇总
    git命令行相关问题汇总记录如下:在本地创建git仓库并关联远程仓库后,无法正常拉取远程更新报错信息:fatal:refusingtomergeunrelatedhistories解决方案:gitpulloriginmaster--allow-unrelated-histories解决git使用ssh无法访问服务器的问题报错信息:Error:Unab......
  • 题解:CF1957A Stickogon
    CF1957AStickogon题意题意十分简单,给予你\(n\)个棍子,问这些棍子可以构成多少个正多边形。思路说是可以构成多少个正多边形,所以我们可以用边最少的正多边形等边三角形来计数。在输入\(a\)的时候,用一个数组\(f\)来计算\(a\)出现的次数,当\(f_{a}\)等于\(3\)时,答案......
  • java代码运行出现DENIED Redis is running in protected mode because protected mode
    这个错误是因为开启了保护模式,导致出错。所以需要关闭redis的保护模式。编辑redis的redis.config  注释bind127.0.0.1 、修改protected-mode为no、修改 daemonize为no然后重启redis ......
  • [题解]ABC351 D~F
    D-GridandMagnet[明天更]E-JumpDistanceSum一开始想到的思路很复杂,先把\(n\)个点按照\(x+y\mod\2\)分成\(2\)组,对于每一组用线段树维护……总之很繁多,虽然有完整的思路,理论上也应该可行,但是实现太麻烦就看题解了。题目描述的距离叫切比雪夫距离,也就是\(x\)坐标之差......
  • [CISCN 2022 东北]hana 题解(易语言逆向)
    [CISCN2022东北]hana脱壳过程首先看一下程序信息程序检测到了UPX的特征,但是下面的特征又显示是VMP壳使用010Editor打开文件将两个VMP0和VMP1改成UPX0和UPX1并保存文件,接下来使用UPX脱壳分析程序这里需要用到一个易语言反编译插件以及一个易语言函数查询网站IDA易语......
  • AtCoder Beginner Contest 351
    B-SpottheDifference难度:⭐题目大意给定两个矩阵,找不同解题思路数据很小,暴力就行;神秘代码#include<bits/stdc++.h>#defineintunsignedlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#defineendl'\n'usingnamespa......
  • Codeforces Round 941 (Div. 1) 题解(A-C)
    比赛链接:https://codeforces.com/contest/1965官解链接:https://codeforces.com/blog/entry/128914比较手速的一场,C与D之间出现了较大的gifficultygap。所幸C题猜得比较快(虽然证明其实比较难),最终rank190,performance2525,成功压线拿下Grandmaster。cpchenpi,堂堂上红!......