单调队列求调qwqwq,用第二个点测试总是5943
#include <bits/stdc++.h>
using namespace std;
const int N=207,inf=0x80808080;
int f[N][N][N],q[N],*bg=q,*ed=q,dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1},n,m,k,ans;
char mp[N][N];
void solve(int t,int bgx,int bgy,int len,int d){
for(int i=1,x=bgx,y=bgy;(1<=x)&&(x<=n)&&(1<=y)&&(y<=m);i++,x+=dx[d],y+=dy[d]){
if(mp[x][y]=='x'){
bg=ed=q;
f[t][x][y]=inf;
continue;
}
int v=f[t-1][x][y]-i;
while((ed!=bg)&&(ed[-1]<v)) ed--;
*(ed++)=v;
while((ed-bg)>(len+1)) bg++;
// for(int p=0;p<=len;p++){
// if(mp[x-p*dx[d]][y-p*dy[d]]=='x') break;
// f[t][x][y]=max(f[t][x][y],f[t-1][x-p*dx[d]][y-p*dy[d]]+p);
// }
ans=max(ans,f[t][x][y]=(*bg)+i);
}
}
int main(){
freopen("P2254_2.in","r",stdin);
ios::sync_with_stdio(0);
cin.tie(0);
int x,y;
cin>>n>>m>>x>>y>>k;
memset(f,0x80,sizeof(f)),memset(mp,'x',sizeof(mp));
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>mp[i][j];
f[0][x][y]=0;
for(int i=1;i<=k;i++){
int l,r,d;
cin>>l>>r>>d;
if(d==1) for(int j=1;j<=m;j++) solve(i,n,j,r-l+1,d);
if(d==2) for(int j=1;j<=m;j++) solve(i,1,j,r-l+1,d);
if(d==3) for(int j=1;j<=n;j++) solve(i,j,m,r-l+1,d);
if(d==4) for(int j=1;j<=n;j++) solve(i,j,1,r-l+1,d);
// for(int j=1;j<=n;j++) for(int k=1;k<=m;k++) cout<<f[i][j][k]<<" \n"[k==m];
// cout<<'\n';
}
cout<<ans<<'\n';
}