题目分析
预处理每个点经过的牛数
c
n
t
i
,
j
cnt_{i, j}
cnti,j,每次更改一个点的指向时,计算更改前的终点坐标 Old
和更改后的终点坐标 New
(不要忘了修改是一直保留的,在计算终点的过程中要顺便更改途经点的牛数和出发点的路牌方向 ,某蒟蒻在这个问题上调了 10min)。
新答案是旧答案
a
n
s
ans
ans 减去出发点牛数
c
n
t
x
,
y
cnt_{x, y}
cntx,y 与 旧终点花费 a[oldx][oldy].x
的积, 加上出发点牛数
c
n
t
x
,
y
cnt_{x, y}
cntx,y 与 新终点花费 a[newx][newy].x
的积。
代码:
#include<bits/stdc++.h>
using namespace std;
const long long NR = 15 * 1e2 + 1;
struct Node{
Node(){
c = '@';
}
char c;
long long x;
}a[NR + 10][NR + 10]; //结构体存储输入
char s[NR + 10];
long long cnt[NR + 10][NR + 10];
int main(){
long long n;
scanf("%lld", &n);
//读入
for(long long i = 1;i <= n;i++){
scanf("%s", s + 1);
for(long long j = 1;j <= n;j++){
a[i][j].c = s[j];
}
scanf("%lld", &a[i][n + 1].x);
}
for(long long j = 1;j <= n;j++){
scanf("%lld", &a[n + 1][j].x);
}
//预处理每个点经过的牛数
for(long long i = 1;i <= n + 1;i++){
for(long long j = 1;j <= n + 1;j++){
if(i == n + 1 && j == n + 1) continue;
if(i <= n && j <= n){ //住所
if(a[i - 1][j].c == 'D'){
cnt[i][j] += cnt[i - 1][j];
}
if(a[i][j - 1].c == 'R'){
cnt[i][j] += cnt[i][j - 1];
}
cnt[i][j]++;
}
else{ //饲料桶
if(i == n + 1){
if(a[i - 1][j].c == 'D'){
cnt[i][j] += cnt[i - 1][j];
}
}
else if(j == n + 1){
if(a[i][j - 1].c == 'R'){
cnt[i][j] += cnt[i][j - 1];
}
}
}
}
}
//计算最初花费
long long sum = 0;
for(long long i = 1;i <= n;i++){
sum += 1ll * cnt[n + 1][i] * a[n + 1][i].x;
sum += 1ll * cnt[i][n + 1] * a[i][n + 1].x;
}
printf("%lld\n", sum); //输出
//处理更改
long long T;
scanf("%lld", &T);
while(T--){
long long x, y;
scanf("%lld%lld", &x, &y); //读入
//计算旧路径
long long posx = x, posy = y;
while(posx != n + 1 && posy != n + 1){
if(a[posx][posy].c == 'D'){
posx++;
}
else if(a[posx][posy].c == 'R'){
posy++;
}
cnt[posx][posy] -= cnt[x][y];
}
long long tmpx = posx, tmpy = posy;
posx = x, posy = y;
//更改方向
if(a[posx][posy].c == 'D'){
a[posx][posy].c = 'R';
}
else if(a[posx][posy].c == 'R'){
a[posx][posy].c = 'D';
}
//计算新路径
while(posx != n + 1 && posy != n + 1){
if(a[posx][posy].c == 'D'){
posx++;
}
else if(a[posx][posy].c == 'R'){
posy++;
}
cnt[posx][posy] += cnt[x][y];
}
//计算并输出
printf("%lld\n", sum - cnt[x][y] * a[tmpx][tmpy].x
+ cnt[x][y] * a[posx][posy].x);
sum -= cnt[x][y] * a[tmpx][tmpy].x;
sum += cnt[x][y] * a[posx][posy].x;
}
return 0;
}