CF1598E. Staircases 2100 —— dp

1598E

 通过数组dp[0/1][i][j]表示以(i, j)结尾的楼梯数量,1表示横着的,0表示竖着的

初始值把所有dp[0/1][i][j]赋值为1,但这样会导致所有长度为1的楼梯被统计了两次,故用tot记录长度为1的楼梯

注意考虑line 68 70的情况(边界条件不要忘记重新赋值1)

注意line 77 82 88 89,向后更新时如果后续某个点已经被锁定(不能作为阶梯),则置0

// Decline is inevitable,
// Romance will last forever.
#include <bits/stdc++.h>
using namespace std;
//#define mp make_pair
#define pii pair<int,int>
#define pb push_back
#define fi first
#define se second
#define ll long long
#define LL long long
#define bug(x) cout << x << '\n'
#define int long long
const int maxn = 1e3 + 10;
const int maxm = 1e3 + 10;
const int INF = 0x3f3f3f3f;
const int dx[] = {0, 0, -1, 1}; //{0, 0, 1, 1, 1,-1,-1,-1}
const int dy[] = {1, -1, 0, 0}; //{1,-1, 1, 0,-1, 1, 0,-1}
const int P = 1e9 + 7;
int dp[2][maxn][maxn];  //0表示以竖着结尾 1表示横着结尾
int n, m, q;
int ans, tot;
int a[maxn][maxn];
void init() {
    ans = 0;
    tot = n * m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j<= m; j++)
            for(int k = 0; k < 2; k++)
            {
                dp[k][i][j] = 1;
                a[i][j] = 1;
            }
    for(int i = 1; i <= n; i++)
        for(int j =1; j <= m; j++) {
            if(i > 1) dp[0][i][j] = dp[1][i-1][j] + 1;
            if(j > 1) dp[1][i][j] = dp[0][i][j-1] + 1;
        }
    for(int i = 1; i <= n; i++)
        for(int j =1; j <= m; j++)
            for(int k = 0; k < 2;k ++)
                ans += dp[k][i][j]; //初始的ans
    
}
void solve() {
    cin >> n >> m >> q;
    init();
    while(q--) {
        int x , y;
        cin >> x >> y;
        a[x][y] = 1 - a[x][y];
//        cerr << a[x][y] << endl;
        if(a[x][y] == 0) {
            tot--;
            for(int k = 0; k < 2; k++)
            {
                ans -= dp[k][x][y];
                dp[k][x][y] = 0;
            }
            for(int k = 0; k < 2; k++)
                ans += dp[k][x][y];
        }
        else {
            tot++;
            for(int k = 0; k < 2; k++)
                ans -= dp[k][x][y];
            if(x > 1) dp[0][x][y] = dp[1][x-1][y] + 1;
            else dp[0][x][y] = 1;
            if(y > 1) dp[1][x][y] = dp[0][x][y-1] + 1;
            else dp[1][x][y] = 1;
            for(int k = 0; k < 2; k++)
                ans += dp[k][x][y];
        }
        while(x <= n && y <= m) {
            if(x  < n) {
                ans -= dp[0][x+1][y];
                dp[0][x + 1][y] = (dp[1][x][y] + 1) * a[x+1][y];
                ans += dp[0][x+1][y];
            }
            if(y < m) {
                ans -= dp[1][x][y + 1];
                dp[1][x][y + 1] = (dp[0][x][y] + 1) * a[x][y+1];
                ans += dp[1][x][y + 1];
            }
            if(x < n && y < m) {
                for(int k = 0; k < 2; k++)
                    ans -= dp[k][x+1][y+1];
                dp[1][x+1][y+1] = (dp[0][x+1][y] + 1) * a[x+1][y+1];
                dp[0][x+1][y+1] = (dp[1][x][y+1] + 1) * a[x+1][y+1];
                for(int k = 0; k < 2; k++)
                    ans += dp[k][x + 1][y + 1];
            }
            x++; y++;
        }
        cout << ans - tot << '\n';
    }
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int T; scanf("%d", &T); while(T--)
//    freopen("1.txt","r",stdin);
//    freopen("2.txt","w",stdout);
//    int T; cin >> T;while(T--)
    solve();
    return 0;
}
/*
 
 
 
 */

猜你喜欢

转载自blog.csdn.net/m0_59273843/article/details/120990409