Problem - D - Codeforces
关键在于如果是环的话,环中的每一个的值都是一样的
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int nn;cin>>nn;
while(nn--){
int n;cin>>n;
int a[n+1],i=0;while(++i<=n)cin>>a[i];
string s;cin>>s;s=" "+s;
int st[n+1]={0},res[n+1]={0};
i=0;while(++i<=n){
if(!st[i]){//如果有一个环,那么这个环他们的ans都是一样的
int ans=0;while(!st[i]){
st[i]=1;ans+=s[i]=='0';i=a[i];
}
while(st[i]!=2){//2表示已经确定了的
res[i]=ans;st[i]=2;i=a[i];
}
}
if(i!=n)cout<<res[i]<<' ';
else cout<<res[i]<<endl;
}
}
}
Problem - E - Codeforces
进行操作删除(最多一次)和替代使得string变成交替字串
首先ans=n-奇数某字符的个数-偶数某字符的个数,某字符指个数最大的
然后难在奇数时怎么快速删除,我们使用计数前缀和(方便个人记忆弄的名字)示例如下:
#include<bits/stdc++.h>
using namespace std;
int main() {//二维的数量前缀和,ans=n-奇数某字符的个数-偶数某字符的个数,某字符指个数最大的
int nn; cin >> nn;
while (nn--) {
int n; cin >> n;
string s; cin >> s; s = " " + s;
if (n & 1) {//要删除一个
int f1[n+1][26 + 1], f2[n+1][26 + 1];
memset(f1, 0, sizeof f1); memcpy(f2, f1, sizeof(f1));
int i = 0, ans = 1e9; while (++i <= n) {
int c = s[i] - 'a' + 1;
int j=0;while(++j<=26)f1[i][j]=f1[i-1][j],f2[i][j]=f2[i-1][j];
if (i & 1)f1[i][c]+= 1;
else f2[i][c] += 1;
}
i = 0; while (++i <= n) {
int odd = 0, even = 0;//删除i后,奇数/偶数的最大个数
int j = 0; while (++j <= 26) {
odd = max(odd, f2[n][j] - f2[i][j] + f1[i - 1][j]);
even = max(even, f1[n][j] - f1[i][j] + f2[i - 1][j]);
}
ans = min(ans, n - odd - even);
}
cout << ans << endl;
}
else {
int f1[26 + 1], f2[26 + 1]; memset(f1, 0, sizeof f1); memset(f2, 0, sizeof f2);
int i = 0; while (++i <= n) {
int c = s[i] - 'a' + 1;
if (i & 1)f1[c]++;
else f2[c]++;
}
int odd = 0, even = 0;
i = 0; while (++i <= 26) {
odd = max(odd, f1[i]);
even = max(even, f2[i]);
}
cout << n - odd - even << endl;
}
}
}