CF2170D Almost Roman

思路

首先我们对每个数字进行分析:

  • $I$ 权值最大为 $1$,最小为 $-1$,
  • $V$ 权值为 $5$,
  • $X$ 权值为 $10$。

注意到无论在何种情况下,$X$ 的权值和造成的影响一定比 $V$ 多 $5$。
可以把原字符串中的所有 $X$ 替换成 $V$,每替换一次就给总权值加 $5$。
又发现对于任意位置,填 $I$ 一定比填另外两个更优。
所以我们先将所有问号的位置都填上 $I$,如果不够就再替换成另外两个。
对于每一次替换,有以下三种情况:

  • 增加了权值为 $-1$ 的 $I$ 的个数,
  • 权值为 $-1$ 的 $I$ 的个数不变,
  • 减少了权值为 $-1$ 的 $I$ 的个数。

显然我们应先替换第一种,再替换第二种,最后选第三种。
那代码就很好实现了。

代码

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
78
79
80
81
82
83
84
85
#include<bits/stdc++.h>
#define fir first
#define sec second
#define int long long
#define pii pair<int,int>
#define fep(i,s,e) for(int i=s;i<e;i++)
#define pef(i,s,e) for(int i=s;i>e;i--)
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define per(i,s,e) for(int i=s;i>=e;i--)
namespace FastIO{
template<typename T>inline void read(T &x){
x=0;int f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);x*=f;
}
template<typename T,typename...Args>
inline void read(T &x,Args&...args){
read(x);
read(args...);
}
template<typename T>void print(T x){
if(x<0)x=-x,putchar('-');
if(x>9)print(x/10);
putchar((x%10)^48);
}
}
using namespace std;
using namespace FastIO;
int T,n,q;
string s;
int calc(){
int ans=0;
fep(i,0,s.size()){
if(s[i]=='I'&&i+1<s.size()&&s[i+1]=='V')
ans--;
else{
if(s[i]=='I')ans++;
else ans+=5;
}
}
return ans;
}
signed main(){
read(T);
while(T--){
read(n,q);
cin>>s;
int ans=0,tmp=0,S=0,num=0;
fep(i,0,n){
if(s[i]=='X'){
s[i]='V';
ans+=5;
}
}
fep(l,0,n){
int r=l;
if(s[l]!='?')continue;
while(r<n&&s[r]=='?')r++;
int len=r-l;
if(l>0&&s[l-1]=='I')len++;
if(r<n&&s[r]=='V'){
tmp--;
len++;
}
num+=(r-l);
l=r-1;
S+=len%2;
tmp+=len/2;
}
fep(i,0,n)if(s[i]=='?')s[i]='I';
ans+=calc();
while(q--){
int a,b,c;
read(a,b,c);
int vcnt=max(0ll,min(b,num-c));
int xcnt=max(0ll,num-c-b);
int nans=ans,rep=vcnt+xcnt;
nans+=vcnt*4+xcnt*9;
nans-=min(tmp,rep)*2;
rep-=(tmp+S);
nans+=max(0ll,rep)*2;
print(nans);puts("");
}
}
}