CF1598E-Staircases【计数】
生活随笔
收集整理的這篇文章主要介紹了
CF1598E-Staircases【计数】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1598E
題目大意
給出一個(gè)n×mn\times mn×m的網(wǎng)格圖,開(kāi)始所有都是黑色的,qqq次取反一個(gè)格子的顏色,然后求樓梯的數(shù)量。
樓梯定義為全黑色的下/右交替的格子集。
1≤n,m≤1000,1≤q≤1041\leq n,m\leq 1000,1\leq q\leq 10^41≤n,m≤1000,1≤q≤104
解題思路
注意到其實(shí)是兩個(gè)斜行交錯(cuò),可以考慮把坐標(biāo)軸旋轉(zhuǎn)45°45°45°,然后發(fā)現(xiàn)其實(shí)就是相鄰的兩行的正方形數(shù)量。
fi,jf_{i,j}fi,j?表示格子(i,j)(i,j)(i,j)所在斜行再往(i,j)(i,j)(i,j)左上角的能延伸多少個(gè)黑色,然后每次O(n)O(n)O(n)暴力修改即可。
時(shí)間復(fù)雜度:O(qn)O(qn)O(qn)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1100; ll n,m,q,w[N][N],a[N][N],ans; ll calc(ll x,ll y) {if(y<0)return 0;return min(x,y+1)+min(x,y); } signed main() {scanf("%lld%lld%lld",&n,&m,&q);for(ll i=1;i<=n;i++) for(ll j=1;j<=m;j++)w[i][j]=w[i-1][j-1]+1;for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++)ans+=calc(w[i][j],w[i-1][j])+calc(w[i][j],w[i][j-1])-1;while(q--){ll x,y;scanf("%lld%lld",&x,&y);if(a[x][y]){ll dx=x,dy=y;x++;y++;while(x<=n&&y<=m&&!a[x][y]){ans-=calc(w[x][y],w[x-1][y])+calc(w[x][y],w[x][y-1])-1;ans-=calc(w[x][y],w[x+1][y]-1)+calc(w[x][y],w[x][y+1]-1);x++;y++;}x=dx;y=dy;a[x][y]^=1;while(x<=n&&y<=m&&!a[x][y])w[x][y]=w[x-1][y-1]+1,x++,y++;x=dx;y=dy;while(x<=n&&y<=m&&!a[x][y]){ans+=calc(w[x][y],w[x-1][y])+calc(w[x][y],w[x][y-1])-1;ans+=calc(w[x][y],w[x+1][y]-1)+calc(w[x][y],w[x][y+1]-1);x++;y++;}}else{ll dx=x,dy=y;while(x<=n&&y<=m&&!a[x][y]){ans-=calc(w[x][y],w[x-1][y])+calc(w[x][y],w[x][y-1])-1;ans-=calc(w[x][y],w[x+1][y]-1)+calc(w[x][y],w[x][y+1]-1);x++;y++;}x=dx;y=dy;a[x][y]^=1;w[x][y]=0;x++;y++;while(x<=n&&y<=m&&!a[x][y])w[x][y]=w[x-1][y-1]+1,x++,y++;x=dx;y=dy;x++;y++;while(x<=n&&y<=m&&!a[x][y]){ans+=calc(w[x][y],w[x-1][y])+calc(w[x][y],w[x][y-1])-1;ans+=calc(w[x][y],w[x+1][y]-1)+calc(w[x][y],w[x][y+1]-1);x++;y++;}}printf("%lld\n",ans);} }總結(jié)
以上是生活随笔為你收集整理的CF1598E-Staircases【计数】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux修改文件的权限命令(linux
- 下一篇: 特斯拉新功能允许车主关闭远程启动功能,防