zoukankan      html  css  js  c++  java
  • CF1598EStaircases【计数】

    正题

    题目链接:https://www.luogu.com.cn/problem/CF1598E


    题目大意

    给出一个\(n\times m\)的网格图,开始所有都是黑色的,\(q\)次取反一个格子的颜色,然后求楼梯的数量。

    楼梯定义为全黑色的下/右交替的格子集。

    \(1\leq n,m\leq 1000,1\leq q\leq 10^4\)


    解题思路

    注意到其实是两个斜行交错,可以考虑把坐标轴旋转\(45°\),然后发现其实就是相邻的两行的正方形数量。

    \(f_{i,j}\)表示格子\((i,j)\)所在斜行再往\((i,j)\)左上角的能延伸多少个黑色,然后每次\(O(n)\)暴力修改即可。

    时间复杂度:\(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);
    	}
    }
    
  • 相关阅读:
    Smali基本语法
    图片智能缩小
    How to install ia32-libs in Ubuntu 14.04 LTS (Trusty Tahr)
    [操作系统][Ubuntu 14.04] 安装Flash 安装QQ2013
    eclipse在Ubuntu 13.04下的安装过程及问题小记
    Android系统手机端抓包方法
    Android 开源框架ActionBarSherlock 和 ViewPager 仿网易新闻客户端
    试用Android Annotations
    Android Annotations 介绍
    盘点国内Android移动广告平台的现状
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15455820.html
Copyright © 2011-2022 走看看