因为只有3行,不能往左走,所以可以从左往右dp。
dp[1][i]=min(dp[1][i-1]+1,dp[2][i-1]+2,dp[3][i-1]+3)
dp[2][i]=min(dp[1][i-1]+2,dp[2][i-1]+1,dp[3][i-1]+2)
dp[3][i]=min(dp[1][i-1]+3,dp[2][i-1]+2,dp[3][i-1]+1)
发现可以将转移转化为(+,mn)矩阵
[dp1,dp2,dp3]*
[1,2,3]
[2,1,2]
[3,2,1]
当不能走的时候定义为INF,之后的每次的修改可以通过线段树维护。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128=__int128;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using db = double;
using ldb = long double;
#define F first
#define S second
#define debug(x) cerr<<#x<<":"<<x<<"\n";
#define debugv(v) cerr<<#v<<":\n";for(int i=0;i<v.size();i++) cerr<<v[i]<<" ";cerr<<"\n";
const int N=2e5+10;
char mp[4][N];
int n;
const int INF=1e9;
struct matrix{
int a[4][4];
matrix(){
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
a[i][j]=INF;
}
}
}
};
matrix operator*(const matrix &x,const matrix &y){
matrix ans;
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
for(int k=1;k<=3;k++){
ans.a[i][j]=min(ans.a[i][j],x.a[i][k]+y.a[k][j]);
}
}
}
return ans;
}
struct node{
int l,r;
matrix sum;
}t[N<<2];
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
void pushup(int p){
t[p].sum=t[ls(p)].sum*t[rs(p)].sum;
}
matrix b[N];
void build(int p,int l,int r){
t[p]={l,r};
if(l==r){
t[p].sum=b[l];
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void update(int pos,int p,matrix d){
if(t[p].l==t[p].r&&pos==t[p].l){
t[p].sum=d;
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(pos<=mid) update(pos,ls(p),d);
else update(pos,rs(p),d);
pushup(p);
}
void change(int i){
bool c1=true,c2=true,c3=true;
if(mp[1][i]=='#') c1=false;
if(mp[2][i]=='#') c2=false;
if(mp[3][i]=='#') c3=false;
b[i].a[1][1]=(c1?1:INF);
b[i].a[2][1]=(c1&&c2?2:INF);
b[i].a[3][1]=(c1&&c2&&c3?3:INF);
b[i].a[1][2]=(c1&&c2?2:INF);
b[i].a[2][2]=(c2?1:INF);
b[i].a[3][2]=(c2&&c3?2:INF);
b[i].a[1][3]=(c1&&c2&&c3?3:INF);
b[i].a[2][3]=(c2&&c3?2:INF);
b[i].a[3][3]=(c3?1:INF);
}
void solve(){
cin>>n;
for(int i=1;i<=3;i++){
for(int j=1;j<=n;j++){
cin>>mp[i][j];
}
}
for(int i=1;i<=n;i++){
change(i);
}
build(1,1,n);
int q;cin>>q;
while(q--){
int x,y;cin>>x>>y;
if(mp[x][y]=='#') mp[x][y]='.';
else mp[x][y]='#';
change(y);
update(y,1,b[y]);
int ans=t[1].sum.a[1][3];
if(ans==INF) ans=0;
cout<<ans-1<<"\n";
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t=1;
// cin>>t;
while(t--) solve();
return 0;
}

京公网安备 11010502036488号