【NOI2019模拟2019.7.1】三格骨牌(轮廓线dp转杨图上钩子定理)
Description

\(n,m<=1e4,mod ~1e9+7\)
题解:
显然右边那个图形只有旋转90°和270°后才能放置。
先考虑一个暴力的轮廓线dp:
假设已经放了编号前i的骨牌,那么这些骨牌形成的图形一定是杨表那样的。
对轮廓线来考虑,不妨设1表示向上走,0表示向右走。
初始状态是:111…(n个1)000..(m个0)
那么四种转移为:
- 1110->0111
- 1000->0001
- 1010->0011
- 1100->0101
这样暴力dp应该能过n,m<=10的。
观察这四种转移,中间的两位都不变,只是把第1位的1移到第4位。
那么按\(mod~3\)分开做,问题变为有一个x+y长的01序列,一开始是x个1+y个0.
每次可以把一个1和紧接的0交换,求最后变为x个0+y个1的方案数。
再把这个转到x×y的杨图上去,一开始轮廓线紧贴左边界和上边界,每次可以把轮廓线的一行改宽一列,且还要满足轮廓线的性质,其实这就是x×y的杨图个数,套钩子定理即可。
那么\(Ans=(xy)!/\prod_{i=0}^{n-1}\prod_{j=1}^{m-1}(i+j+1)!\)
Code:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int fac[34000100];
int _,n,m;
int main() {
freopen("trominoes.in", "r", stdin);
freopen("trominoes.out", "w", stdout);
ll s=1;
fac[0]=1;
rep(i,1,34000000) fac[i]=(ll)fac[i-1]*i%mod;
for (scanf("%d",&_);_;_--) {
scanf("%d%d",&n,&m);
if (n*m%3!=0) {
puts("0");
continue;
}
if (n%3!=0) swap(n,m);
ll ret=fac[n*m/3],rg=1;
rep(i,0,m) {
ret=ret*fac[i/3]%mod;
rg=rg*fac[i/3+n/3]%mod;
}
ret=ret*powmod(rg,mod-2)%mod;
printf("%lld\n",ret);
}
}
【NOI2019模拟2019.7.1】三格骨牌(轮廓线dp转杨图上钩子定理)的更多相关文章
- [LeetCode] Domino and Tromino Tiling 多米诺和三格骨牌
We have two types of tiles: a 2x1 domino shape, and an "L" tromino shape. These shapes may ...
- [JZOJ6244]【NOI2019模拟2019.7.1】Trominoes 【计数】
Description n,m<=10000 Solution 考虑暴力轮廓线DP,按顺序放骨牌 显然轮廓线长度为N+M 轮廓线也是单调的 1表示向上,0表示向右 N个1,M个0 只能放四种骨牌 ...
- [JZOJ6247]【NOI2019模拟2019.6.27】C【计数】
Description n<=200000 Solution 比赛时没做出这道题真的太弟弟了 首先我们从小到大插入数i,考虑B中有多少个区间的最大值为i 恰好出现的次数不太好计算,我们考虑计算最 ...
- [JZOJ6244]【NOI2019模拟2019.7.1】islands【计数】【图论】
Description n<=1e9,M,K<=100 Solution 显然任选m个港口的答案是一样的,乘个组合数即可. 考虑枚举m个港口的度数之和D 可以DP计算 记\(F_{m,D} ...
- [JZOJ6241]【NOI2019模拟2019.6.29】字符串【数据结构】【字符串】
Description 给出一个长为n的字符串\(S\)和一个长为n的序列\(a\) 定义一个函数\(f(l,r)\)表示子串\(S[l..r]\)的任意两个后缀的最长公共前缀的最大值. 现在有q组询 ...
- 【NOI2019模拟2019.6.29】字符串(SA|SAM+主席树)
Description: 1<=n<=5e4 题解: 考虑\(f\)这个东西应该是怎样算的? 不妨建出SA,然后按height从大到小启发式合并,显然只有相邻的才可能成为最优答案.这样的只 ...
- 【NOI2019模拟2019.6.29】组合数(Lucas定理、数位dp)
Description: p<=10且p是质数,n<=7,l,r<=1e18 题解: Lucas定理: \(C_{n}^m=C_{n~mod~p}^{m~mod~p}*C_{n/p} ...
- 【NOI2019模拟2019.7.4】朝夕相处 (动态规划+BM)
Description: 题解: 这种东西肯定是burnside引理: \(\sum置换后不动点数 \over |置换数|\) 一般来说,是枚举置换\(i\),则\(对所有x,满足a[x+i]=a[i ...
- 【NOI2019模拟2019.6.27】B (生成函数+整数划分dp|多项式exp)
Description: \(1<=n,k<=1e5,mod~1e9+7\) 题解: 考虑最经典的排列dp,每次插入第\(i\)大的数,那么可以增加的逆序对个数是\(0-i-1\). 不难 ...
随机推荐
- 【LeetCode】二分
[475] Heaters [Easy] 给你一排房子,一排加热器.找到能warm所有房子的最小加热器半径. 思路就是对于每个房子,找离它最近的左右两台heater, 分别求距离.温暖这个房子的hea ...
- Fabric.js的使用
最近项目有一个绘制的功能,搜了一圈发现fabric.js口碑不错,但是文档稀缺,于是东看看西搜搜的把项目的需求都给实现了,想分享一下. 篇幅有点长,但看完后可以轻松驾驭fabric.我的项目是基于VU ...
- java随笔记录
JAVA的变量类型 类变量:独立于方法之外的变量,用 static 修饰. 实例变量:独立于方法之外的变量,不过没有 static 修饰. 局部变量:类的方法中的变量. public class Va ...
- 微信小程序截取字符串
我这里用的 str.substring(star,end)第一个参数代表开始位置,第二个参数代表结束位置的下一个位置;若参数值为负数,则将该值转为0;两个参数中,取较小值作为开始位置,截取出来的字符串 ...
- 管理mysql
要管理MySQL,可以使用可视化图形界面MySQL Workbench. MySQL Workbench可以用可视化的方式查询.创建和修改数据库表,但是,归根到底,MySQL Workbench是一个 ...
- sql delete语句
如果要删除数据库表中的记录,我们可以使用DELETE语句. DELETE语句的基本语法是: DELETE FROM <表名> WHERE ...; 例如,我们想删除students表中id ...
- NOIp2018集训test-10-23
上午考了一套sb题,但是没有人AK.李巨290虐场. 下午又考了一套sb题,李巨AK虐场.%%% T1 % 中国剩余定理好像做不了啊,我一直在想如何用CRT做,然后就GG了. 然而正解是bike当初说 ...
- JAVA调用R脚本
0 前言R是一种非常方便易用的绘图.统计分析.ML算法设计方面的脚本语言.实际中有这样一种场景:算法工程师用R搭建了机器学习算法模型,想用于javaweb之中但是又不想重新用java写一遍算法模型,那 ...
- 使用并行ssh提高工作效率
我们经常需要ssh到多个主机上执行相同的命令,为了提高效率,我们通常会自己写个脚本,循环遍历执行我们的命令,比如: for host in `cat hosts.txt`;do ssh usernam ...
- 专题:NFSv4 file server
Network File System (NFS) is a file system protocol that allows client machines to access network at ...