Solution -「AGC 026D」Histogram Coloring
\(\mathcal{Description}\)
Link.
有 \(n\) 列下底对齐的方格纸排成一行,第 \(i\) 列有 \(h_i\) 个方格。将每个方格染成黑色或白色,求使得任意完整 \(2\times2\) 矩形内恰有两个白色(和两个黑色)的方案数。答案模 \(10^9+7\)。
\(n\le100\),\(h_i\le10^9\)
\(\mathcal{Solution}\)
小清新 DP 题叭。
首先考虑在完整的网格图里染色,若某一行完成染色,那么下一行的方案并不多:
- 若当前行存在相邻同色格,则下一行必须为当前行颜色取反;
- 否则即当前行为黑白或白黑交替,则下一行可以与当前行全部相同或全部相反。
把这一结论放在本题,建出小根笛卡尔树(根据题意,当前区间最小值应缩为一点,严格意义上不是笛卡尔树,不难意会 qwq),DP。转移问题形如将若干小块网格下面垫一大块完整网格图,求方案数。所以,令 \(f(u,0/1)\) 表示完成 \(u\) 所代表区间的染色,且最下一层是否是黑白交替状的方案数。转移平凡,可参考易读的代码。
转移里有个快速幂,最终复杂度为 \(\mathcal O(n\log h)\)。
\(\mathcal{Code}\)
/* Clearink */
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
const int MAXN = 100, MOD = 1e9 + 7;
int n, h[MAXN + 5];
int node, ecnt, lef[MAXN + 5], rig[MAXN + 5],
hgt[MAXN + 5], tot[MAXN + 5], head[MAXN + 5];
struct Edge { int to, nxt; } graph[MAXN + 5];
inline int mul( const long long a, const int b ) { return a * b % MOD; }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
inline int mpow( int a, int b ) {
int ret = 1;
for ( ; b; a = mul( a, a ), b >>= 1 ) ret = mul( ret, b & 1 ? a : 1 );
return ret;
}
inline void link( const int s, const int t ) {
graph[++ecnt] = { t, head[s] }, head[s] = ecnt;
}
inline int build( const int l, const int r ) {
if ( l > r ) return 0;
int u = ++node;
hgt[u] = 0x3f3f3f3f, tot[u] = 0;
lef[u] = l, rig[u] = r;
rep ( i, l, r ) {
if ( h[i] < hgt[u] ) hgt[u] = h[i], tot[u] = 0;
tot[u] += h[i] == hgt[u];
}
for ( int i = l, j; i <= r; i = j + 1 ) {
if ( h[j = i] == hgt[u] ) continue;
while ( j + 1 <= r && h[j + 1] != hgt[u] ) ++j;
int v = build( i, j );
link( u, v ), hgt[v] -= hgt[u];
}
return u;
}
int f[MAXN + 5][2];
inline void solve( const int u ) {
int &f0 = f[u][0] = 1, &f1 = f[u][1] = 2, len = rig[u] - lef[u] + 1;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
solve( v = graph[i].to ), len -= rig[v] - lef[v] + 1;
f0 = mul( f0, add( f[v][0], add( f[v][1], f[v][1] ) ) ),
f1 = mul( f1, f[v][1] );
}
f0 = mul( f0, mpow( 2, len ) ),
subeq( f0, f1 ),
f1 = mul( f1, mpow( 2, hgt[u] - 1 ) );
}
int main() {
scanf( "%d", &n );
rep ( i, 1, n ) scanf( "%d", &h[i] );
solve( build( 1, n ) );
printf( "%d\n", add( f[1][0], f[1][1] ) );
return 0;
}
Solution -「AGC 026D」Histogram Coloring的更多相关文章
- Solution -「AGC 036D」「AT 5147」Negative Cycle
\(\mathcal{Descriprtion}\) Link. 在一个含 \(n\) 个结点的有向图中,存在边 \(\lang i,i+1,0\rang\),它们不能被删除:还有边 \(\l ...
- Solution -「AGC 016F」Games on DAG
\(\mathcal{Description}\) Link. 给定一个含 \(n\) 个点 \(m\) 条边的 DAG,有两枚初始在 1 号点和 2 号点的棋子.两人博弈,轮流移动其中一枚棋 ...
- Solution -「AGC 004E」「AT 2045」Salvage Robots
\(\mathcal{Description}\) Link. 有一个 \(n\times m\) 的网格.每个格子要么是空的,要么有一个机器人,要么是一个出口(仅有一个).每次可以命令所有机 ...
- Solution -「AGC 012F」「AT 2366」Prefix Median
\(\mathcal{Description}\) Link. 给定序列 \(\{a_{2n-1}\}\),将 \(\{a_{2n-1}\}\) 按任意顺序排列后,令序列 \(b_i\) 为前 ...
- Solution -「AGC 010C」「AT 2304」Cleaning
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的无根树,点有点权,每次选择两个不同的叶子,使它们间的简单路径的所有点权 \(-1\),问能否将所有点 ...
- Solution -「AGC 019E」「AT 2704」Shuffle and Swap
\(\mathcal{Description}\) Link. 给定 \(01\) 序列 \(\{A_n\}\) 和 \(\{B_n\}\),其中 \(1\) 的个数均为 \(k\).记 \( ...
- Solution -「AGC 019F」「AT 2705」Yes or No
\(\mathcal{Description}\) Link. 有 \(n+m\) 个问题,其中 \(n\) 个答案为 yes,\(m\) 个答案为 no.每次你需要回答一个问题,然后得知这个 ...
- Solution -「AGC 013E」「AT 2371」Placing Squares
\(\mathcal{Description}\) Link. 给定一个长度为 \(n\) 的木板,木板上有 \(m\) 个标记点,第 \(i\) 个标记点距离木板左端点的距离为 \(x_i\ ...
- Solution -「AGC 003D」「AT 2004」Anticube
\(\mathcal{Description}\) Link. 给定 \(n\) 个数 \(a_i\),要求从中选出最多的数,满足任意两个数之积都不是完全立方数. \(n\le10^5\) ...
随机推荐
- vue js 格式化时间
常用于iview日期组件时间处理 /** * @param {Number} num 数值 * @returns {String} 处理后的字符串 * @description 如果传入的数值小于10 ...
- Vue下路由History mode 出现404,无法正常刷新
在History mode下,如果直接通过地址栏访问路径,那么会出现404错误,这是因为这是单页应用(废话)-其实是因为调用了history.pushState API 所以所有的跳转之类的操作都是通 ...
- 接口神器之 Json Server 详细指南
简介 json-server 是一款小巧的接口模拟工具,一分钟内就能搭建一套 Restful 风格的 api,尤其适合前端接口测试使用. 只需指定一个 json 文件作为 api 的数据源即可,使用起 ...
- Kubernetes 中的 Pod 安全策略
来源:伪架构师作者:崔秀龙很多人分不清 SecurityContext 和 PodSecurityPolicy 这两个关键字的差别,其实很简单:•SecurityContext 是 Pod 中的一个字 ...
- IDEA导入Web项目配置Tomcat启动
1.导入项目 2.配置project 3.导入项目模块 配置Models 4.配置Libraries 5. 6. 7.配置tomcat
- [CAN波形分析] 一次CAN波形分析之旅
Prepare CAN通信协议使用了有一段时间了,但都是基于软件层面的使用,对于其波形不是很了解,正好这段时间比较闲,是时候补补硬知识. 开始之前,先介绍一下设备: 咸鱼淘来的古董级别示波器GDS-2 ...
- ManualResetEvent实现线程的暂停与恢复
背景 前些天遇到一个需求,在没有第三方源码的情况下,刷新一个第三方UI,并且拦截到其ajax请求的返回结果.当结果为AVALIABLE的时候,停止刷新并语音提示,否则继续刷新. 分析这个需求,发现需要 ...
- C++内嵌汇编 教程1
注:本文的所有代码是在我自己的VS2008中测试的,由于环境的差别,不能保证能在所有的编译器上运行. 1.内嵌汇编介绍 在C++中,可以通过__asm关键字来嵌入汇编语言.例如 int main(){ ...
- Servlet Cookie的使用
HTTP(超文本传输协议)是一个基于请求与响应模式的无状态协议.无状态主要指 2 点: 协议对于事务处理没有记忆能力,服务器不能自动维护用户的上下文信息,无法保存用户状态: 每次请求都是独立的,不会受 ...
- py调用shell
py调用shell