Codeforces1598 E. Staircases(思维,暴力,组合)

Posted live4m

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1598 E. Staircases(思维,暴力,组合)相关的知识,希望对你有一定的参考价值。

题意:


解法:

先dp处理出所有格子free时的方案数:
d[i][j][0/1]表示(i,j)作为左下拐点/右上拐点的方案数即可.

然后考虑每次操作之后的方案数变化量.
对于每次操作有多少条路径经过了修改的点.

上图中绿色点是修改的点,考虑这个点作为左下的拐点,
计算出左上的红色点数和右下的红色点数,乘起来就是方案数.

考虑这个点作为右上的拐点同理.

单次操作的复杂度O(n+m)

code:

#include<bits/stdc++.h>
// #define MULTI_CASE
#define SYNC_OFF
#define PI pair<int,int>
#define ll long long
#define int long long
using namespace std;
// const int mod=998244353;
const int mod=1e9+7;
const int maxm=2e6+5;
int d[1111][1111][2];//0表示作为右上角,1表示作为左下角
int a[1111][1111];
vector<PI>dir[4]{
    vector<PI>{{0,-1},{-1,0}},//左,上
    vector<PI>{{1,0},{0,1}},//下,右
    vector<PI>{{-1,0},{0,-1}},//上,左
    vector<PI>{{0,1},{1,0}},//右,下
};
int n,m,q;
void solve(){
    cin>>n>>m>>q;
    //0表示作为右上角,1表示作为左下角
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            d[i][j][0]=d[i][j][1]=1;
            d[i][j][0]+=d[i][j-1][1];
            d[i][j][1]+=d[i-1][j][0];
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            ans+=d[i][j][0];
            ans+=d[i][j][1];
            ans--;//孤立点重复计算了一次
        }
    }
    //
    for(int i=1;i<=q;i++){
        int x,y;cin>>x>>y;
        int cnt[4]={0};
        for(int k=0;k<4;k++){
            int q=x,e=y;
            int p=0;
            cnt[k]=1;
            while(1){
                q+=dir[k][p].first;
                e+=dir[k][p].second;
                if(q<1||q>n||e<1||e>m||a[q][e])break;
                cnt[k]++;
                p^=1;
            }
        }
        /*
            vector<PI>{{0,-1},{-1,0}},//左,上
            vector<PI>{{1,0},{0,1}},//下,右
            vector<PI>{{-1,0},{0,-1}},//上,左
            vector<PI>{{0,1},{1,0}},//右,下
        */
        int res=cnt[0]*cnt[1]+cnt[2]*cnt[3]-1;
        ans+=res*(a[x][y]?1:-1);
        a[x][y]^=1;
        cout<<ans<<endl;
    }
}
void Main(){
    #ifdef MULTI_CASE
    int T;cin>>T;while(T--)
    #endif
    solve();
}
void Init(){
    #ifdef SYNC_OFF
    ios::sync_with_stdio(0);cin.tie(0);
    #endif
    #ifndef ONLINE_JUDGE
    freopen("../in.txt","r",stdin);
    freopen("../out.txt","w",stdout);
    #endif
}
signed main(){
    Init();
    Main();
    return 0;
}

以上是关于Codeforces1598 E. Staircases(思维,暴力,组合)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces1598 F. RBS(状压dp,预处理)

Codeforces Codeforces Round #484 (Div. 2) E. Billiard

codeforces 598E E. Chocolate Bar(区间dp)

Codeforces 292 E. Copying Data (线段树)

E. Boxers ( Codeforces Round #579 )

CodeForces E. Lucky Array 幸运数列