首页 > 其他分享 >AT_hhkb2020_e Lamps 题解

AT_hhkb2020_e Lamps 题解

时间:2024-03-18 15:03:01浏览次数:14  
标签:方案 int 题解 long Lamps mp text hhkb2020 方块

\(\mathtt{TAG}\): 计数、数学

变量说明

下文中 \(k\) 指整洁方块个数。

First. 如何计数?

一个方案一个方案地数肯定是不现实的,不妨反过来想:每个方块在多少个方案中被照亮。

Second. 如何求多少个方案

首先预处理出有多少位置可以将 \(s_{i,j}\) 照亮。记为 \(x\)。这个很简单,不再赘述。

那么只需要这 \(x\) 个方块中任意一个被点亮,\(s_{i, j}\) 就可以被照亮。

排除掉全关的情况,只对于这 \(x\) 个方块的方案数为 \(2^x - 1\)(因为总方案为 \(2^x\))。

其余方块不影响,所以可以任意排列,即 \(2^{k - x}\) 种方案。

根据乘法原理,\(x\) 个方块的选取每种都要对应其余方块的 \(2^{k - x}\) 种选取,所以 \(s_{i,j}\) 被选中的情况即为 \((2^x - 1) \times 2^{k - x}\)。

然后该方块的贡献即为被选中的方案数。

最后答案即为每个整洁方块的贡献之和。

时间复杂度

预处理:\(\text{O}(4\times nm)\)

计数:\(\text{O}(nm)\)

总时间复杂度:\(\text{O}(5\times nm)\)

提示

十年 OI 一场空,不开 long long 见祖宗。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
const int N = 2000 + 10;
const int mod = 1e9 + 7;
#define endl '\n'
int n;
int h, w, k;
char mp[N][N];
int l[N][N], r[N][N], u[N][N], d[N][N];
int fac[N *N];
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> h >> w;
	for (int i = 1; i <= h; i ++) {
		for (int j = 1; j <= w; j ++) {
			mp[0][j] = mp[h + 1][j] = '#';
			cin >> mp[i][j];
			if(mp[i][j] != '#') k ++;
		}
		mp[i][0] = mp[i][w + 1] = '#';
	}
	fac[0] = 1;
	for (int i = 1; i <= k; i ++) fac[i] = fac[i - 1] * 2 % mod; // 预处理 2 ^ i
	for (int i = 1; i <= h; i ++) {
		for (int j = 1; j <= w; j ++) {
			if(mp[i][j - 1] != '#') l[i][j] = l[i][j - 1] + 1;
			else l[i][j] = 0;
		}
		for (int j = w; j >= 1; j --) {
			if(mp[i][j + 1] != '#') r[i][j] = r[i][j + 1] + 1;
			else r[i][j] = 0;
		}
	}
	for (int j = 1; j <= w; j ++) {
		for (int i = 1; i <= h; i ++) {
			if(mp[i - 1][j] != '#') u[i][j] = u[i - 1][j] + 1;
			else u[i][j] = 0;
		}
		for (int i = h; i >= 1; i --) {
			if(mp[i + 1][j] != '#') d[i][j] = d[i + 1][j] + 1;
			else d[i][j] = 0;
		}
	}
	int ans = 0;
	for (int i = 1; i <= h; i ++) {
		for (int j = 1; j <= w; j ++) {
			if(mp[i][j] == '#') continue;
			int cnt = l[i][j] + r[i][j] + d[i][j] + u[i][j] + 1;
			ans += (fac[cnt] - 1 + mod) % mod * fac[k - cnt] % mod;
			ans %= mod;
		}
	}
	cout << ans << endl;
	return 0;
}

标签:方案,int,题解,long,Lamps,mp,text,hhkb2020,方块
From: https://www.cnblogs.com/Ice-lift/p/18080406

相关文章

  • CF933-Div3 大致思路+题解
    A-RudolfandtheTicket纯水题暴力枚举直接过$code$#include<bits/stdc++.h>#definefo(x,y,z)for(int(x)=(y);(x)<=(z);(x)++)#definefu(x,y,z)for(int(x)=(y);(x)>=(z);(x)--)inlineintqr(){ charch=getchar();intx=0,f=1; for(;ch<'0......
  • 【题解】A18535.来自领导的烦恼
    题目跳转思路:本题可以使用动态规划或递归的方式来实现,本质上是一道01背包的变型题。假设一共有\(n\)名员工,每一位员工的技能水平用\(a[i]\)表示。要使得两个部门的员工技能总和之差最小,意思就是尽可能地将一个部门的技能之和”凑“到\(\sum\limits_{i=1}^{n}a[i]\times\frac{1}......
  • 【题解】A18536.星光交错的律动
    题目跳转思路:这道题可能跟博弈论有一点关系,没有学习过博弈论做起来应该问题也不大。思考一个问题,先手必胜的前提是什么?有关更多的内容可以前往:浅谈有向无环图先手必胜的前提是,在任何一种局面下,先手都有至少一种操作可以使后手处于必败的局面。若先手进行任何操作后,后手都可以......
  • 【题解】A18537.我心中珍藏的游戏
    题目跳转思路:题目问最多可以获得的额外伤害,其实就是询问在这些技能中,如何怎样选取一个最优的发动技能顺序使得攻击加成最大。我们可以把每一个技能看作成一个图的顶点,把每一个攻击加成看作图的边,权制为\(Ei,j\)。由于\(Ei,j\)与\(Ej,i\)相等,则可以将这个图视为无向图。可以样样......
  • 【题解】P2627 [USACO11OPEN] Mowing the Lawn G
    【题解】P2627[USACO11OPEN]MowingtheLawnG题目跳转数据量比较大,暴力肯定是不行的。只能考虑用动态规划的方式来做。这道题有许多dp设计的思路,这里提供两个:方法一:普通状态设计定义\(dp[i][1/0]\)表示截止遍历到第\(i\)个元素时,选择第\(i\)个元素或不选第\(i\)个元素可以......
  • cfRound933div3-E题解
    E-RudolfandkBridges题意:选择的桥在连续的行中,每个桥的支架安装位置是可以不一样的.做法:赛时也感觉也感觉是dp,但是害怕dp,就选择了逃避.往贪心方向想,认为每次到了每个跳板都要跳到最远距离,实际上这样是不行的.很明显,可能存在近一点的点花费更少。实际上是dp,而且也不......
  • [ABC258F] Main Street 题解
    题意:你要在平面直角坐标系中行走,每一步可以上下左右四个方向任意移动$1$,耗时$k$秒。特别地,存在若干条快速通道,若该步起点和终点均满足$x\equiv0\pmod{B}$或$y\equiv0\pmod{B}$,则认为该步是在快速通道上进行,仅需耗时$1$秒。询问从$(S_x,S_y)$到$(G_x,G_y)$最......
  • P3939 数颜色 题解
    题目链接:数颜色经典题目了,暴力数据结构随便过,不过这种不带修的单个颜色的数量查找有个经典的做法:分桶+二分。具体的为每个颜色分桶,记录有序下标,这样就可以二分出\([l,r]\)上的下标个数。对于一次交换来说,如果相邻的颜色相同那么并不会发生交换,如果不同那么就发生交换,由于下标在......
  • P10218 [省选联考 2024] 魔法手杖 题解
    Description给定\(a_1,a_2,\dots,a_n\)以及\(b_1,b_2,\dots,b_n\),满足\(a_i\in[0,2^k-1]\)以及\(b_i\geq0\),你需要给出\(S\subseteq\{1,2,\dots,n\}\)以及\(x\in[0,2^k-1]\)满足以下条件:\(\sum\limits_{i\inS}b_i\leqm\);满足以上条件的前提下,最大化\......
  • P2746 [USACO5.3] 校园网Network of Schools 题解
    题目链接:校园网NetworkofSchools这个题得翻译下题目意思才知道在干嘛,题目一开始表明了这个是一个有向图,因为边是单向的。其次关于第一个问题:基于一个事实,如果有\(x\rightarrowy\rightarrowz\),那么只需要\(x\)接受协议,它所在的\(scc\)强连通分量上的点一定都能不需要......