其实这是个论文题我会乱说?
我大概是我见过的最简单的NOI题了吧
然而并没有用论文里的的方法(虽然是黑科技但是好麻烦啊)
这个东西嘛,很明显每次转移都是区域化的。
然后单调队列维护乱搞一下
代码写得好丑QAQ没治了
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int inf=1e9;
int f[2][205][205],up[205][205][4];
int q[205],h,t,now,last;
int n,m;
char mp[205][205];
void push(int x){
while(h<=t&&q[t]<x)t--;
q[++t]=x;
}
void pop(int x){
if(q[h]==x)h++;
}
void solve1(int l){
for(int j=1;j<=m;j++){
h=0;t=-1;
int d=0,ed=n;
for(int i=n;i>=1;i--){
d--;push(f[last][i][j]+d);
if(mp[i][j]=='x'){
f[now][i][j]=-inf;
continue;
}
int tmp=min(up[i][j][0],i+l);
while(ed>tmp){
pop(f[last][ed][j]+d+ed-i);
ed--;
}
f[now][i][j]=q[h]-d;
}
}
}
void solve2(int l){
for(int j=1;j<=m;j++){
h=0;t=-1;
int d=0,ed=1;
for(int i=1;i<=n;i++){
d--;push(f[last][i][j]+d);
if(mp[i][j]=='x'){
f[now][i][j]=-inf;
continue;
}
int tmp=max(up[i][j][1],i-l);
while(ed<tmp){
pop(f[last][ed][j]+d+i-ed);
ed++;
}
f[now][i][j]=q[h]-d;
}
}
}
void solve3(int l){
for(int i=1;i<=n;i++){
h=0;t=-1;
int d=0,ed=m;
for(int j=m;j>=1;j--){
d--;push(f[last][i][j]+d);
if(mp[i][j]=='x'){
f[now][i][j]=-inf;
continue;
}
int tmp=min(up[i][j][2],j+l);
while(ed>tmp){
pop(f[last][i][ed]+d+ed-j);
ed--;
}
f[now][i][j]=q[h]-d;
}
}
}
void solve4(int l){
for(int i=1;i<=n;i++){
h=0;t=-1;
int d=0,ed=1;
for(int j=1;j<=m;j++){
d--;push(f[last][i][j]+d);
if(mp[i][j]=='x'){
f[now][i][j]=-inf;
continue;
}
int tmp=max(j-l,up[i][j][3]);
while(ed<tmp){
pop(f[last][i][ed]+d+j-ed);
ed++;
}
f[now][i][j]=q[h]-d;
}
}
}
int main(){
//freopen("a.in","r",stdin);
int x,y;
scanf("%d%d%d%d",&n,&m,&x,&y);
now=0;last=1;
memset(f[now],-0x3f,sizeof(f[now]));
f[now][x][y]=0;
int k;scanf("%d",&k);
for(int i=1;i<=n;i++)
scanf("%s",mp[i]+1);
for(int i=1;i<=n;i++){
up[i][m+1][2]=m;
for(int j=m;j>=1;j--)
if(mp[i][j]=='x')up[i][j][2]=j-1;
else up[i][j][2]=up[i][j+1][2];
up[i][0][3]=1;
for(int j=1;j<m;j++)
if(mp[i][j]=='x')up[i][j][3]=j+1;
else up[i][j][3]=up[i][j-1][3];
}
for(int j=1;j<=m;j++){
up[n+1][j][0]=n;
for(int i=n;i>=1;i--)
if(mp[i][j]=='x')up[i][j][0]=i-1;
else up[i][j][0]=up[i+1][j][0];
up[0][j][1]=1;
for(int i=1;i<=n;i++)
if(mp[i][j]=='x')up[i][j][1]=i+1;
else up[i][j][1]=up[i-1][j][1];
}
while(k--){
int si,ti,di;scanf("%d%d%d",&si,&ti,&di);
now^=1;last^=1;
if(di==1)solve1(ti-si+1);
else if(di==2)solve2(ti-si+1);
else if(di==3)solve3(ti-si+1);
else solve4(ti-si+1);
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=max(ans,f[now][i][j]);
printf("%d\n",ans);
return 0;
}
卧槽,下一篇论文讲的就是这个Σ( ° △ °|||)︴
好吧其实我想说的是我没用那个诡异的指针运算