因为只有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;
}