「6月雅礼集训 2017 Day2」B
【题目大意】
求n*n的棋盘,每行每列都有2个黑格子的方案数。
n<=10^7
【题解】
zzq的做法好神奇啊
行列建点,二分图
左边有i个点,右边有j个点的方案数 f[i,j]
左边有i个点,2个已经有1个度,右边有j个点的方案数 g[i,j]
g[i,j] = f[i-2,j-1]*j + g[j,i-2]*P(j,2)
f[i,j] = g[i,j-1] * C(i,2) = g[j,i-1] * C(j,2)
g[j,i-2] = g[i-1,j-1] * C(i-1,2) / C(j,2)
g[i,j] = g[i-2,j-2] * C(i-2,2) * j + g[i-1, j-1] * C(i-1,2) / C(j,2) * P(j,2)
g[i,j] = g[i-2,j-2] * C(i-2,2) * j + g[i-1, j-1] * C(i-1,2) * 2
g[x] = g[x, x-1]
g[x] = g[x-2] * C(x-2, 2) * (x-1) + g[x-1] * C(x-1, 2) * 2
ans = sigma (C(x,2) * g[x])
Q: 为什么从f转移到g,只乘了右边选择的部分,不管左边;从g转移到f,只乘了左边的部分,不管右边?
A: g实际的意义是我钦定左边最后两个度数为1的方案数,f实际的意义是我钦定右边最后1或2个是我最后填进来。 我从g到f,目的是消去两个度为1的点,重点是消去,我要优先考虑消除哪两个点,按照我g的定义,每两个度数为1的点作为选择,都有这么多方案,所以要乘组合数;从f到g,目的是制造两个度为1的点,按照f的定义,每1或2个点作为选择,都有这么多方案,所以要乘j和后面的那个组合数。意义在于,我要有一个顺序来填数,不能xjb填,这样会统计重复方案,我们用钦(ying)点来避免这样的问题。
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; # define RG register
# define ST static const int M = 1e7 + ;
const int mod = ; int n, g[M], ans; inline int C(int n, int k = ) {
return (ll)n * (n-) / % mod;
} int main() {
// freopen("B.in", "r", stdin);
// freopen("B.out", "w", stdout);
cin >> n;
g[] = , g[] = ;
for (int i=; i<=n; ++i) {
g[i] = 1ll * C(i-) * (i-) % mod * g[i-] % mod + 2ll * C(i-) * g[i-] % mod;
if(g[i] >= mod) g[i] -= mod;
}
for (int i=; i<=n; ++i) {
ans += 1ll * C(i) * g[i] % mod;
if(ans >= mod) ans -= mod;
}
cout << ans;
return ;
}
多贴几份考试写的各种暴力吧qwq
O(n^2)求单点暴力
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; # define RG register
# define ST static const int M = 1e4 + , N = 1e5 + ;
const int mod = ; int n, f[][M];
// row i, line2: j line1: k line0: l inline int C(int n, int k) {
if(k == ) return n;
if(k == ) return (ll)n * (n-) / % mod;
} int main() {
// freopen("B.in", "r", stdin);
// freopen("B.out", "w", stdout);
int pre = , cur = ; cin >> n;
for (int j=; j<=n; ++j) f[pre][j] = ;
f[pre][] = ;
for (int i=; i<=n; ++i) {
for (int j=; j<=i; ++j) {
f[cur][j] = ;
// i*2 = j*2 + k => k = i*2 - j*2
int k = i* - j*, l = n-j-k;
// printf("%d line2: %d line1: %d line0: %d\n", i, j, k, l);
if(l < ) continue;
if(j >= ) {
f[cur][j] += 1ll * C(k+, ) * f[pre][j-] % mod;
if(f[cur][j] >= mod) f[cur][j] -= mod;
}
if(k >= ) {
f[cur][j] += 1ll * C(l+, ) * f[pre][j] % mod;
if(f[cur][j] >= mod) f[cur][j] -= mod;
}
if(j && k) {
f[cur][j] += 1ll * C(k, ) * C(l+, ) * f[pre][j-] % mod; // 10w: need mod again
if(f[cur][j] >= mod) f[cur][j] -= mod;
}
// printf("F = %d\n", f[i][j]);
}
swap(pre, cur);
}
cout << f[pre][n] << ','; return ;
}
把含有n-...的项换成不含n的等价表示就有70分了。。
我是考试的时候打了个1w的表发现100K,压了一半,套这个做法。。50(被评测机卡)
「6月雅礼集训 2017 Day2」B的更多相关文章
- 「6月雅礼集训 2017 Day2」C
[题目大意] 有一棵n个点的完全二叉树,边权均为1,每个点有小鸟容量c[i] 依次来了m只小鸟,第i只小鸟初始位置在pos[i]上,问来了x只小鸟的时候,怎样安排小鸟的路线可以使得小鸟移动的边权和最小 ...
- 「6月雅礼集训 2017 Day2」A
[题目大意] 给出一棵树,求有多少对点(u,v)满足其路径上不存在两个点a,b满足(a,b)=1 n<=10^5 [题解] 考虑找出所有不符合的点对,共有n*ln(n)对,他们要么是祖先-> ...
- 「6月雅礼集训 2017 Day10」quote
[题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...
- 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)
原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 | ...
- 「6月雅礼集训 2017 Day11」delight
[题目大意] 有$n$天,每天能吃饭.睡觉.什么事也不干 每天吃饭的愉悦值为$e_i$,睡觉的愉悦值为$s_i$,什么都不干愉悦值为0. 要求每连续$k$天都要有至少$E$天吃饭,$S$天睡觉. 求最 ...
- 「6月雅礼集训 2017 Day11」jump
[题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...
- 「6月雅礼集训 2017 Day11」tree
[题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...
- 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)
[题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...
- 「6月雅礼集训 2017 Day8」route
[题目大意] 给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串. $n \leq 5000$ [题解] 考虑取凸包上一点,然后如果下一个是‘R' ...
随机推荐
- Notepad++删除空行的多种实现办法
Notepad++支持基础的正则表达式,同时由于自身丰富的插件和功能,所以删除空行或有空格的空行,有多种实现办法,条条大路通罗马,闪电博客抛砖引玉,供大家参考. 一.删除空行(不包括有空格类符号的空行 ...
- 复制MySQL数据库A到另外一个MySQL数据库B(仅仅针对innodb数据库引擎)
方案一:(不用太大的变化my.ini文件) copy 原数据库A中的 数据库(database) ib_logfile1 ib_logfile0 ibdata1: 关闭目的数据库B: 备份 ...
- 思杰VDI提示“The VDI is not available”
前言:困扰已久的问题终于解决. 问题:客户反馈无法连接VDI. 解决过程:1.登录后台查看VDI状态为关机状态尝试重新启动提示如下图: 2.判断此VDI的启动盘出现问题(注:本人环境无数据盘) 3.查 ...
- jmeter操作JDBC
1. 依次添加计划.线程组.JDBC Connection Configuration.JDBC Request.HTTP请求.Debug Sampler.察看结果树 在计划中导入mysql的jdbc ...
- Servlet入门(2)
1.url_pattern匹配模式 2.servlet生命周期 3.servlet线程问题 一.url_pattern 1.定义: 当浏览器发起一个url请求后,该请求发送到servlet容器的时候, ...
- 使用gradle打包时将依赖也合并入jar包
有些情形需要将项目依赖的jar包也合并入自己项目的jar包内,出来的这个jar我们称它为fat-jar.我所使用的方法需要用到shadow插件: 下面例子展示将mybatis打入我的jar包,并将my ...
- HDU 1028 整数拆分问题 Ignatius and the Princess III
Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- mysql ibd 文件还原数据
-- 这里要还原的表名为 test_table -- 1建库,并选中库,库名随意 -- 2查看InnoDB 引擎独立表空间是否开启 SHOW VARIABLES LIKE '%per_table%' ...
- 【bzoj4976】宝石镶嵌 乱搞+dp
题目描述 从$n$个数中选出$n-k$个,使得它们的二进制或(or)最大.输出这个值. 输入 第一行包含两个正整数$n,k(2\le n\le 100000,1\le k\le 100,k<n) ...
- hdu DIY FLIGHT GAME (dfs)
FLIGHT GAME Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total S ...