题解:AT_abc350_f [ABC350F] Transpose

赛时:一眼平衡树,不会写。

思路

模拟。

维护一个 dfs\tt dfs,其中 dfs(l,r,f)\texttt{dfs(l,r,f)} 表示现在模拟的区间是 [l,r][l,r],正序还是倒序。

但是路途中可能会遇到括号,这时我们就要反方向模拟。

因此,我们需要预处理出每个左括号对应的右括号(右括号同理)。

这样,我们就能 O(1)\operatorname{O}(1) 地进入下一个模拟。

关于大小写转换,手搓几组样例就不难发现:

  • 如果正序输出,大小写不变。
  • 如果倒序输出,大小写互换。

这样,我们就能 O(n)\operatorname{O}(n) 地解决本题了。

#include<bits/stdc++.h>
using namespace std;
string s;
int n,ld[500005],rd[500005];
stack<int>st;
void dfs(int l,int r,int f) {
	if(f==1) {
		for(int i=l; i<=r; i++) {
			if(s[i]=='('){
				dfs(i+1,ld[i]-1,-1);
				i=ld[i];
			} 
			else{
				cout<<s[i];
			}
		}
	}
	else{
		for(int i=r;i>=l;i--){
			if(s[i]==')'){
				dfs(rd[i]+1,i-1,1);
				i=rd[i];
			} 
			else{
				if('a'<=s[i]&&s[i]<='z')cout<<char(s[i]-'a'+'A');
				else cout<<char(s[i]-'A'+'a');
			}
		}
	}
}
int main() {
	cin>>s;
	n=s.length();
	s=' '+s;
	for(int i=1; i<=n; i++) {
		if(s[i]=='(') {
			st.push(i);
		}
		if(s[i]==')') {
			int v=st.top();
			st.pop();
			ld[v]=i;
			rd[i]=v;
		}
	}
	dfs(1,n,1);
	return 0;
}
posted @   Weslie_qwq  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示