祈祷中...

题意:

给定一个长度为 $n$ 的字符串,有 $m$ 次操作,每次操作给定两个整数 $t$ 和 $x$,以及一个字符 $c$,满足以下操作:

$\hspace{1em}\bullet$ 若 $t$ 为 $1$,则将字符串中的第 $x$ 个字符更改为 $c$

$\hspace{1em}\bullet$ 若 $t$ 为 $2$,则将字符串中的所有大写字母变为小写字母

$\hspace{1em}\bullet$ 若 $t$ 为 $3$,则将字符串中的所有小写字母变为大写字母

求最后的字符串

思路:

针对操作 $1$,直接更改即可,但是由于这个操作可能会改变原有字符串的性质(全部是大写\全部是小写),所以可以维护一个 $map$,用来判断的是:在上一次使用操作 $2、3$ 后,字符串中的哪些位置又因为操作 $1$ 而更改。

针对操作 $2、3$,因为这两个操作之后,整个字符串要么全为大写,要么全为小写,所以用两个 $bool$ 的 $pd$ 和 $px$ 存储即可。

最后输出的时候,如果 $pd$ 或 $px$ 中有一个为一,这意味着最后一个操作不为操作 $1$,所以直接按大小写输出即可。

否则,意味着最后一步的操作必定为操作 $1$,字符串在改变大小写后又更改了,所以只需判断 $map$ 中当前的位置是否更改,更改的话输出原字符串,否则按最后一个操作 $2、3$ 后的字符串输出。

代码(不喜勿喷)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
template<typename P>
inline void read(P &x){
P res=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
res=res*10+ch-'0';
ch=getchar();
}
x=res*f;
}
int T=1;
int n;
int Q;
char s[500010];
signed main(){
read(n);
for(int i=1;i<=n;++i) cin>>s[i];
read(Q);
int op,x;
char y;
int sumc=0;
bool qd=0,qx=0;
map<int,bool> q;
for(int i=1;i<=Q;++i){
read(op),read(x);
cin>>y;
if(op==1){
s[x]=y;
q[x]=1;
}
else if(op==2){
qx=1,qd=0;
q.clear();
}
else{
qd=1,qx=0;
q.clear();
};
}
if(qx==1){
for(int i=1;i<=n;++i){
if(q[i]==0){
if(s[i]>='A' && s[i]<='Z') cout<<char(s[i]+32);
else cout<<s[i];
}
else cout<<s[i];
}
cout<<endl;
}
else if(qd==1){
for(int i=1;i<=n;++i){
if(q[i]==0){
if(s[i]>='a' && s[i]<='z') cout<<char(s[i]-32);
else cout<<s[i];
}
else cout<<s[i];
}
cout<<endl;
}
else{
for(int i=1;i<=n;++i){
cout<<s[i];
}
cout<<endl;
}
return 0;
}