题解:P12246 电 van
_Deer_Peach_ · · 题解
题意:
给你一个长度为
思路:
暴力解法直接排除,思考怎么快速计算。
我们可以寻找每一个字符
再考虑修改,每次修改只会交换前后的字符,重要的是,每次修改只会影响一个
当
当
都不是则没有影响,因为只有当
每次修改减去当前
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int N=1e6+5;
int n,m;
string s;
int va[N],an[N];
vector<int>a;
int numa;
signed main(){
IOS;
cin>>n>>m;
cin>>s;
s=" "+s;
int numv=0,numn=0;
for(int i=1;i<=n;i++){
if(s[i]=='v')numv++;
if(s[i]=='a'){
va[i]=numv;
a.push_back(i);
numa++;
}
}
for(int i=n;i>=1;i--){
if(s[i]=='n')numn++;
if(s[i]=='a'){
an[i]=numn;
}
}
int ans=0;
for(int i=0;i<numa;i++){
ans=ans+va[a[i]]*an[a[i]];
}
while(m--){
int x;
cin>>x;
int l=0,r=numa-1;
int mid;
while(l<r){
mid=l+r>>1;
a[mid]>=x?r=mid:l=mid+1;
}
int aid=a[r];
if(aid==x){
if(s[x+1]=='a'){
cout<<ans<<endl;
}
if(s[x+1]=='v'){
ans=ans-va[x]*an[x];
swap(va[x],va[x+1]);
swap(an[x],an[x+1]);
va[x+1]++;
ans=ans+va[x+1]*an[x+1];
a[r]++;
cout<<ans<<endl;
}
if(s[x+1]=='n'){
ans=ans-va[x]*an[x];
swap(va[x],va[x+1]);
swap(an[x],an[x+1]);
an[x+1]--;
ans=ans+va[x+1]*an[x+1];
a[r]++;
cout<<ans<<endl;
}
}
else if(aid==x+1){
if(s[x]=='v'){
ans=ans-va[x+1]*an[x+1];
swap(va[x],va[x+1]);
swap(an[x],an[x+1]);
va[x]--;
ans=ans+va[x]*an[x];
a[r]--;
cout<<ans<<endl;
}
if(s[x]=='n'){
ans=ans-va[x+1]*an[x+1];
swap(va[x],va[x+1]);
swap(an[x],an[x+1]);
an[x]++;
a[r]--;
ans=ans+va[x]*an[x];
cout<<ans<<endl;
}
}
else{
cout<<ans<<endl;
}
swap(s[x],s[x+1]);
/*cout<<s<<endl;
for(int i=1;i<=numa;i++){
cout<<a[i-1]<<" ";
cout<<va[a[i-1]]<<" "<<an[a[i-1]]<<endl;
}*/
}
return 0;
}
很明显可以优化,但作者懒得优化(疑似最劣解)。