NOI模拟题4 Problem C: 填格子(board)
Solution
首先我们要有敏锐的直觉: 我们将每一列中不选哪种颜色看作是一个序列, 则我们发现这个序列要求相邻两位的颜色不同. 我们还发现, 一个这样的序列对应两种不同的合法的棋盘, 因此统计合法棋盘数的问题, 就转化为了统计合法序列数.
我们不妨设\(R > G > B\). 我们可以用R将这个序列切成\(R - 1\)或\(R\)或\(R + 1\)段, 这取决于序列的开头/结尾是否放R. 一旦确定了序列开头和结尾是否放R, 我们在后面就只考虑在序列中间放R, 而不考虑开头和结尾. 每一段由G和B交错组成. 我们将这些由G和B组成的段分为以下三类:
- GBGBGB...GB 或 BGBGBG...BG, 即B的个数与G的个数相同. 我们记这样的段有\(x\)段.
- GBGB...GBG, 即G的个数比B多\(1\). 我们记这样的段有\(y\)段.
- BGBG...BGB, 即B的个数比G多1. 我们记这样的段有\(z\)段.
则我们发现\(y - z\)的值是固定的: \(y - z = G - B\).
我们假设\(R\)将该序列分为\(d\)段(根据前文, \(或或d = R - 1或d = R + 1或d = R\)), 则\(x + y + z = d\). 我们再枚举\(x\), 则\(y\)与\(z\)的数量也被确定了. 我们把第二和第三种情况的序列补全为G和B数量相等的情况, 则现在我们总共有\(\frac{G + B + y + z}{2}\)对GB或BG.
我们用插板法在这些BG或GB中插入\(d - 1\)个R即可.
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = (int)1e6, MOD = (int)1e9 + 7;
int pw[M + 1], fac[M + 1], facInv[M + 1];
inline int C(int a, int b)
{
if (a < b) return 0;
return (long long)fac[a] * facInv[a - b] % MOD * facInv[b] % MOD;
}
inline int getInverse(int a)
{
int res = 1;
for (int x = MOD - 2; x; a = (long long)a * a % MOD, x >>= 1) if (x & 1) res = (long long)res * a % MOD;
return res;
}
inline int work(int d, int x, int y)
{
int ans = 0;
for (int a = 0; a <= d - (x - y); ++ a) if (((d - a) - (x - y)) % 2 == 0)
{
int c = ((d - a) - (x - y)) / 2, b = x - y + c;
ans = (ans + (long long)C((x + y + b + c) / 2 - 1, d - 1) * C(d, a) % MOD * C(b + c, b) % MOD * pw[a] % MOD) % MOD;
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("board.in", "r", stdin);
freopen("board.out", "w", stdout);
#endif
pw[0] = 1; for (int i = 1; i <= M; ++ i) pw[i] = pw[i - 1] * 2 % MOD;
fac[0] = facInv[0] = 1; for (int i = 1; i <= M; ++ i) fac[i] = (long long)fac[i - 1] * i % MOD, facInv[i] = getInverse(fac[i]);
int T; scanf("%d", &T);
for (int cs = 0; cs < T; ++ cs)
{
int m, R, G, B; scanf("%d%d%d%d", &m, &R, &G, &B);
R = m - R; G = m - G; B = m - B;
if (G < B) swap(G, B);
if (R < G) swap(R, G);
if (G < B) swap(G, B);
int ans = (long long)2 * ((long long)work(R - 1, G, B) + 2 * work(R, G, B) + work(R + 1, G, B)) % MOD;
printf("%d\n", ans);
}
}
NOI模拟题4 Problem C: 填格子(board)的更多相关文章
- NOI模拟题1 Problem A: sub
题面 Sample Input 5 7 2 -1 -3 1 1 1 2 1 3 3 4 3 5 2 1 3 0 2 1 2 1 2 1 1 -3 2 Sample Output 2 4 5 2 HIN ...
- NOI模拟题6 Problem C: Circle
Solution 首先这个矩阵, 很明显的就是Vandermonde矩阵. 我们有公式: \[ |F_n| = \prod_{1 \le j < i \le n} (a_i - a_j) \] ...
- NOI模拟题5 Problem A: 开场题
Solution 注意到\(\gcd\)具有结合律: \[ \gcd(a, b, c) = \gcd(a, \gcd(b, c)) \] 因此我们从后往前, 对于每个位置\(L\), 找到每一段不同的 ...
- NOI模拟题4 Problem B: 小狐狸(fox)
Solution 考虑分开统计朝向每一个方向的所有狐狸对答案的贡献. 比如说以向右为例, 我们用箭标表示每一只狐狸的方向, 用\('\)表示当前一步移动之前的每一只狐狸的位置. \[ \begin{a ...
- NOI模拟题4 Problem A: 生成树(mst)
Solution 我们考虑答案的表达式: \[ ans = \sqrt{\frac{\sum_{i = 1}^{n - 1} (w_i - \overline{w})^2}{n - 1}} \] 其中 ...
- 花海漫步 NOI模拟题
题目好像难以看懂? 题目大意 给出一个字符串\(S\),统计满足以下条件的\((i,j,p,q)\)的数量. \(i \leq j, p \leq q\) \(S[i..j],S[p..q]\)是回文 ...
- 神奇的矩阵 NOI模拟题
神奇的矩阵 题目大意 有一个矩阵\(A\),第一行是给出的,接下来第\(x\)行,第\(y\)个元素的值为数字\(A_{x-1,y}\)在\(\{A_{x-1,1},A_{x-1,2},A_{x-1, ...
- Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题
Problem K. UTF-8 Decoder 题目连接: http://opentrains.snarknews.info/~ejudge/team.cgi?SID=c75360ed7f2c702 ...
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem I. Interest Targeting 模拟题
Problem I. Interest Targeting 题目连接: http://codeforces.com/gym/100714 Description A unique display ad ...
随机推荐
- 03018_监听器Listener
1.什么是监听器? (1)监听器就是监听某个对象的状态变化的组件: (2)监听器的相关概念 ①事件源:被监听的对象------三个域对象:request.session.ServletContext ...
- windows控制台主题美化工具-colortool
最近在win10上装了 wsl 系统,发现界面主题太挫,文件夹颜色很不清晰 . 特此在网上搜索了一下,发现了 colortool 这个工具 这是微软官方提供的用于控制台配色的程序 发布版本地址:htt ...
- java web知识点
java web知识点 1.Java知识点 基本数据类型,面向对象,异常,IO,NIO,集合,多线程,JVM,高级特性. 2.web知识点 JSP,Serlvet,JDBC,Http 掌握Cookie ...
- noip 2018 d2t1 旅行
noip 2018 d2t1 旅行 (题目来自洛谷) 给定n个城市,m条双向道路的图, 不存在两条连接同一对城市的道路,也不存在一条连接一个城市和它本身的道路.并且, 从任意一个城市出发,通过这些道路 ...
- JavaWeb笔记(一)JDBC
基本步骤 导入MySQL驱动jar包 mysql-connector-java-8.0.15.zip 注册驱动 获取数据库连接对象Connection 定义sql 获取执行sql语句的对象Statem ...
- zookeeper 集群
集群步骤: 1.安装zookeeper 2.修改zookeeper配置文件 3.创建myid文件 安装zookeeper:查看安装步骤 修改zookeeper配置文件:在zoo.cfg中添加配置 se ...
- myeclipse搭建activemq 简单聊天
需要一起交流的请加群qq:200634530
- 34条简单的SQL优化准则
转载地址:http://bbs.csdn.net/topics/260002113 我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习.摘录.并汇总部分资料与大家分享!(1) ...
- HDU 2896 病毒侵袭(AC自动机水)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- [MUTC2013][bzoj3513] idiots [FFT]
题面 传送门 思路 首先有一个容斥原理的结论:可以组成三角形的三元组数量=所有三元组-不能组成三角形的三元组 也就是说我们只要求出所有不能组成三角形的三元组即可 我们考虑三元组(a,b,c),a< ...