Codeforces Round #578 (Div. 2) 二维差分 可做模板

题意: 在n*n的矩阵中,你可以选择一个k*k的子矩阵,然后将这个子矩阵中的所有B全部变为W,问你怎么选择这个子矩阵使得最终的矩阵中某一行全是W或者某一列全是W的个数最多

题解:考虑每一行和每一列,对于特定的一行来说,要想让其全变为W,那么子矩阵的左上角端点是在一个范围中的,因此我们可以把范围中的每一个值加1

为了速度选择用二维差分来做,最终矩阵中的最大值就是答案

此题可以作为二维差分模板

#include<bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define fore(i, s, t) for (int i = s; i < (int)t; i++)
#define fi first
#define se second
#define ll long long

using namespace std;

const int maxn=2e5+5;

const int inf=2e9;

int dif[2005][2005];//difference array

//from (x1,y1) (x2,y2) add val
void add(int x1,int y1,int x2,int y2,int val){
	dif[x1][y1]+=val;
	dif[x1][y2+1]-=val;
	dif[x2+1][y1]-=val;
	dif[x2+1][y2+1]+=val;
} 

string s[maxn];

int main(){
	int n,k;
	cin>>n>>k;
	for(int i=0;i<n;i++){
		cin>>s[i];
	}
	int res=0;
	for(int i=0;i<n;i++){
		int l=-1,r=-1;
		for(int j=0;j<n;j++){
			if(s[i][j]==‘B‘) {
				if(l==-1) l=j;
				r=j;
			}
		}
		if(l==-1) {
			res++;
			continue;
		}
		if(r-l+1>k) continue;
		add(max(1,i-k+2),max(1,r-k+2),i+1,l+1,1);
	}
	for(int j=0;j<n;j++){
		int l=-1,r=-1;
		for(int i=0;i<n;i++){
			if(s[i][j]==‘B‘) {
				if(l==-1) l=i;
				r=i;
			}
		}
		if(l==-1) {
			res++;
			continue;
		}
		if(r-l+1>k) continue;
		add(max(1,r-k+2),max(j-k+2,1),l+1,j+1,1);
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			dif[i][j]=dif[i][j]+dif[i-1][j]+dif[i][j-1]-dif[i-1][j-1];
			ans=max(ans,dif[i][j]);
		}
	}
	printf("%d\n",ans+res);
}

  

原文地址:https://www.cnblogs.com/033000-/p/12216154.html

时间: 2024-08-30 07:53:37

Codeforces Round #578 (Div. 2) 二维差分 可做模板的相关文章

Codeforces Round #578 (Div. 2)

A.模拟. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8   9 const int N=200010; 10 char s[N]; 11

HDU5465/BestCoder Round #56 (div.2) 二维树状数组

Clarke and puzzle 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一个数c_{i, j}c?i,j??. aa想开挂,想知道如何打败bb. 他们要玩qq次游戏,每一次做一次操作: 1. 取出当中的一个子矩阵(x_1, y_1)-(x_2, y_2)(x?1??,y?1??)−(x?2??,y?2??)玩游戏.两个人轮流行动,每一次只能从这个子矩阵中的一个方格c_{i, j}c?i,j??中减

Codeforces Round #625 Div1 C,二维偏序,排序+线段树

题目 题意: 有若干武器A,攻击力A1,费用A2, 有若干铠甲B,防御力B1,费用B2, 有若干怪兽M,攻击力M1,防御力M2,奖励M3 你可以选择一把武器,一个铠甲,打败所有攻击和防御都严格小的怪兽,问最大收益. 思路: 典型的二维偏序问题,把攻击和防御想象成二维的坐标轴,我们要找到的其实就是一个矩形里(0,0)~(x,y)里收益-这个矩形的花费的最大值.我们可以排序一维,另一维用线段树维护,枚举的时候往里面加怪兽就好. 代码: #include <bits/stdc++.h> using

Codeforces Round #506 (Div. 3) D-F

Codeforces Round #506 (Div. 3) (中等难度) 自己的做题速度大概只尝试了D题,不过TLE D. Concatenated Multiples 题意 数组a[],长度n,给一个数k,求满足条件的(i,j)(i!=j) a[i],a[j]连起来就可以整除k 连起来的意思是 20,5连起来时205; 5,20连起来时520 n<=2*1e5,k<=1e9,ai<=1e9 愚蠢的思路是像我一样遍历(i,j)可能性,然后TLE,因为这是O(n^2) 可以先思考一简单问

Codeforces Round #427 (Div. 2) C. Star sky(二维前缀和)

题目链接:Codeforces Round #427 (Div. 2) C. Star sky 题意: 在一个二维平面上有n个星星,每个星星有一个初始的亮度,每过去一秒,星星的亮度变化为(s+1)%(c+1). 现在有q个询问,问t秒后一个矩形区域的星星的总亮度为多少. 题解: 由于c不大,将每颗星星按照初始亮点分类,每一类在任意时间的亮度都是相同的,然后对应加一加就行了. 1 #include<bits/stdc++.h> 2 #define RT(l,r) (l+r|l!=r) 3 #de

Codeforces Round #371 (Div. 1)

A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给出的01序列相等(比较时如果长度不等各自用0补齐) 题解: 1.我的做法是用Trie数来存储,先将所有数用0补齐成长度为18位,然后就是Trie的操作了. 2.官方题解中更好的做法是,直接将每个数的十进制表示中的奇数改成1,偶数改成0,比如12345,然后把它看成二进制数10101,还原成十进制是2

Codeforces Round #302 (Div. 2) A B C

Codeforces Round #302 (Div. 2) A. Set of Strings 字符串 q 被称为 "beautiful" 当且仅当 q 可以被拆分成 k 个子串 (s1, s2, s3, ... , sk) 并且任意两个字串满足首字母不一样. 直接模拟,对 q 的每个字符进行判断,如果该字符在之前没有出现过,那么从它开始就可以组成一个新的字符串,并且计数,如果到了k 了则把之后的都归为一个字符串. #include <cstring> #include

Codeforces Round #261 (Div. 2)——Pashmak and Graph

题目链接 题意: n个点,m个边的有向图,每条边有一个权值,求一条最长的路径,使得路径上边值严格递增.输出路径长度 (2?≤?n?≤?3·105; 1?≤?m?≤?min(n·(n?-?1),?3·105)) 分析: 因为路径上会有重复点,而边不会重复,所以最开始想的是以边为状态进行DP,get TLE--后来想想,在以边为点的新图中,边的个数可能会很多,所以不行. 考虑一下裸的DP如何做:路径上有重复点,可以将状态详细化,dp[i][j]表示i点以j为结束边值的最长路,但是数据不允许这样.想想

Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo(矩阵)

题目链接:Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo 题意: 在一个二维方格子里有n条线段,有三种走法 (x?+?1,?y?+?1), (x?+?1,?y), or (x?+?1,?y?-?1). 现在要求每次都要在线段下行走,问你有多少种走法, 可以从(0,0)到(k,0). 题解: 考虑dp f[i][j]=f[i-1][j]+f[i-1][j+1]+f[i-1][j-1]. 由于k比较大c比较小,可以考虑用矩阵来优化