zoukankan      html  css  js  c++  java
  • CF1227E Arson In Berland Forest 二分+二维前缀和+差分

    题意:

    在一个无限大的矩阵中,每个位置是一棵树。在一个$ n \times m$ 的子矩阵中,发生了一场火灾,一些树被摧毁了。被摧毁的树用字符 X 表示,未被摧毁的树用字符 . 表示。子矩阵外的树都没有被摧毁。

    • 在 0 时刻,有些树是自发着火的。
    • 接下来的每一分钟内,每一棵着火(也即被摧毁)的树,会使得它周围的 8 个相邻的树着火。
    • 在第 T 分钟初,火灾停止。

    现在给定最后被摧毁的树,求最大可能的 T,并求出任意一种满足的、自发着火的树的集合。

    范围&性质 \(1\leq n,m\leq 10^6,1\leq n\times m\leq 10^6\)

    分析:

    分析可以发现对于小于答案的T,一定满足题意,所以T的大小具有单调性,我们只需要二分出一个T,然后枚举每一个点判断它是否可以作为起始的自燃点,此时的时间复杂度为\(\omicron(nmt^2log)\),为了降低时间复杂度我们采取二维前缀和的方法使检验每一个点能否作为自燃点的复杂度降到\(\omicron(1)\)的,同时对于每一个自燃点覆盖的矩形区域进行差分处理,最后对差分数组进行求和,统计权值为正的点的个数,若等于原有X的个数,则将mid增大反之减小,总的复杂度为\(\omicron(nmlog)\)

    代码:

    吐槽一句这个题真的是赢在码量上,单论思维难度,没有2300的难度

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	const int maxn = 1e6+5;
    	int n,m;
    	vector<int> sum[maxn],tot[maxn];
    	vector<bool> ans[maxn];
    	char ch[maxn];
    	
    	bool check(int x)
    	{
    		for(int i=0;i<=n;i++)
    		{
    			for(int j=0;j<=m;j++)
    			{
    				tot[i][j]=0;
    			}
    		}
    		for(int i=x+1;i<=n-x;i++)
    		{
    			for(int j=x+1;j<=m-x;j++)
    			{
    				if(sum[i+x][j+x]-sum[i-x-1][j+x]-sum[i+x][j-x-1]+sum[i-x-1][j-x-1]==(2*x+1)*(2*x+1))
    				{
    					tot[i+x+1][j+x+1]+=1;
    					tot[i-x][j+x+1]+=-1;
    					tot[i+x+1][j-x]+=-1;
    					tot[i-x][j-x]+=1;
    				}
    			}
    		}
    		
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			{
    				printf("%d",tot[i][j]);
    			}
    			puts(" ");
    		}
    		puts(" ");
    		
    		int cnt=0;
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			{
    				if(tot[i][j]+=tot[i-1][j]+tot[i][j-1]-tot[i-1][j-1])
    				{
    					cnt++;
    				}
    			}
    		}
            for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			{
    				printf("%d",tot[i][j]);
    			}
    			puts(" ");
    		}
    		puts(" ");
    		return cnt==sum[n][m];
    	}
    	
    	void work()
    	{
    		scanf("%d%d",&n,&m);
    		for(int i=0;i<=n+1;i++)
    		{
    			for(int j=0;j<=m+1;j++)
    			{
    				sum[i].push_back(0);
    				tot[i].push_back(0);
    				ans[i].push_back(false);
    			}
    		}
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%s",ch+1);
    			for(int j=1;j<=m;j++)
    			{
    				sum[i][j]=(ch[j]=='X'?1:0);
    				sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    			}
    		}
    		int mid,l=0,r=(min(n,m)-1)/2,res;
    		while(l<=r)
    		{
    			mid=(l+r)>>1;
    			if(check(mid))
    			{
    				res=mid;
    				l=mid+1;
    			}
    			else r=mid-1;
    		}
    		printf("%d\n",res);
    		for(int i=res+1;i<=n-res;i++)
    		{
    			for(int j=res+1;j<=m-res;j++)
    			{
    				if(sum[i+res][j+res]-sum[i-res-1][j+res]-sum[i+res][j-res-1]+sum[i-res-1][j-res-1]==(2*res+1)*(2*res+1))
    				{
    					ans[i][j]=true;
    				}
    			}
    		}
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			{
    				putchar((ans[i][j]?'X':'.'));
    			}
    			puts(" ");
    		}
    	}
    	
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
  • 相关阅读:
    Features for Multi-Target Multi-Camera Tracking and Re-identification论文解读
    CBAM(Convolutional Block Attention Module)使用指南
    j2ee web项目 ssh 中使用junit测试
    log4j 发送日志到邮箱
    java.util.ConcurrentModificationException
    java 项目 报错
    json 传参数到action中 乱码
    TOMCAT 信息
    action 纯注解 笔记
    java 上传图片 打水印
  • 原文地址:https://www.cnblogs.com/youth518/p/13649615.html
Copyright © 2011-2022 走看看