ZOJ3874 Permutation Graph(NTT&&cdq分治)
最近在看几道整体二分还有cdq分治的东西,突然间想起前几个礼拜的ZOJ题,然后看了一下代码,经过了一些深思熟虑之后,发现自己终于看懂了,下面就用别人的代码来剖析一下整个解题的思路吧,具体的内容我再看看。
首先要解决这个问题需要有一些卷积的知识,或者说是多项式乘法,一个很典型的多项式乘法的东东就是FFT,然后原来在数论意义下(即mod P)的意义下,也有相应的NTT(快速数论变换),思想是和FFT一致的,不过在这里原根稍微不一样,而且也不用去管复数,当然我是不会懂的,下面抄个链接:
NTT(快速数论变换) http://blog.csdn.net/zz_1215/article/details/40430041
现在假设自己懂了NTT,然后我们把它当作黑盒,然后就把它当作可以实现mod P意义下卷积的一个工具,然后去理解一下题目的做法。
经过一些理论推导,我们可以发现,实际上我们要求的东西是 dp[n]=n!-(dp[1]*(n-1)!+dp[2]*(n-2)!+... dp[n-1]*1!).
实际上dp[n]=n!- dp[i]和i!的卷积的第n项。这样的一个算法暴力做的话要算到n的话是O(n^2)的,下面看下cdq分治。
个人对cdq分治的理解是这样的:
T(n)=2T(n/2)+O(f(n)) 一个传统的典型的分治算法里,O(f(n))是指的将两个子问题合并的代价,非常典型的就是归并排序。而在cdq分治里,O(f(n))就不一定是合并的代价了,在归并排序里,左子问题对右子问题是没有影响的,而现实的分治里,可能会出现左子问题对右子问题产生影响的情况,及前面的操作是直接对右边操作产生影响的,我们必须先做了左子问题,然后把左子问题的影响加到右子问题,然后才能再递归右子问题。下面的框架给了两种分治的思想吧。
// traditional divide-and-conquer
void solve(l,r)
{
int mid=(l+r)>>1;
solve(l,mid);
solve(mid+1,r);
combine 2 subproblem.
} // cdq divide-and conquer void solve1(l,r)
{
int mid=(l+r)>>1;
solve(l,mid);
add the affect of [l,mid] to [mid+1,r]
solve(mid+1,r);
} void solve2(l,r)
{
int mid=(l+r)>>1;
add the affect of [l,mid] to [mid+1,r];
solve(l,mid);
solve(mid+1,r);
}
下面我们来看看别人的代码里是怎么做的,下面的代码抄自下面的链接,注释是自己给别人加上的,方便一下理解吧。
ZOJ3874:http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=3709562
// dp[l]要求的
// f[l] 是l的阶乘
void solve (int l, int r) {
// 递归边界,l==r时,说明所有比l小的卷积都算完了,所以dp[l]=f[l]-dp[l];
if (l == r) {
dp[l] = (f[l] - dp[l] + P) % P;
return;
}
int m = (l + r) >> 1;
// 递归左子问题,现在要做的是算出dp[l...mid]和f[]的卷积加到dp[mid+1...r]上
solve (l, m);
// 下面的部分就是将dp[l...mid]赋给a,将f的值赋给b,然后做NTT,然后算完之后再逆变换回来
// 做完逆变换后,a[x]存的就是dp和f的卷积的第x项,
int s = 1, n = m - l + 1;
while (s <= n * 2) s <<= 1;
a[0] = b[0] = 0;
for (int i = 1, j = l; i < s; i++, j++) a[i] = (j <= m ? dp[j] : 0);
for (int i = 1; i < s; i++) b[i] = f[i];
NTT (a, s); NTT (b, s);
for (int i = 0; i < s; i++) a[i] = a[i] * b[i] % P;
NTT (a, s, true);
// end
// 将影响加到dp[mid+1...r]上。
for (int i = m + 1, j = m - l + 2; i <= r; i++, j++) (dp[i] += a[j]) %= P;
solve (m + 1, r);
}
最后不难发现将左子问题的影响加到右子问题上其实就是一个O(nlogn)的过程。
T(n)=2T(n/2)+O(nlogn)
所以最后出来的复杂度应该是O(nlog^2n)的。
ZOJ3874 Permutation Graph(NTT&&cdq分治)的更多相关文章
- ZOJ3874 Permutation Graph
Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has a permutation {a1, a2, … an}. He finds ...
- ZOJ3874 Permutation Graph 【分治NTT】
题目链接 ZOJ3874 题意简述: 在一个序列中,两点间如果有边,当且仅当两点为逆序对 给定一个序列的联通情况,求方案数对\(786433\)取模 题解 自己弄了一个晚上终于弄出来了 首先\(yy\ ...
- ZOJ 3874 Permutation Graph 分治NTT
Permutation Graph Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has a permutation {a1, a2 ...
- HDU5322 Hope(DP + CDQ分治 + NTT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...
- hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...
- 【BZOJ-3456】城市规划 CDQ分治 + NTT
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=3456 Solution 这个问题可以考虑dp,利用补集思想 N个点的简单图总数量为$2^{ ...
- BZOJ4555求和(cdq分治+NTT)
题意: 输出f(n)对998244353(7 × 17 × 223 + 1)取模的结果.1 ≤ n ≤ 100000 其中S(i,j)是第二类Stirling数,即有i个球,丢到j个盒子中,要求盒子不 ...
- BNUOJ 51279[组队活动 Large](cdq分治+FFT)
传送门 大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案.两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中 ...
- HDU5730 FFT+CDQ分治
题意:dp[n] = ∑ ( dp[n-i]*a[i] )+a[n], ( 1 <= i < n) cdq分治. 计算出dp[l ~ mid]后,dp[l ~ mid]与a[1 ~ r-l ...
随机推荐
- Servlet过滤器---编码转换过滤器
该实例用于将请求与相应的编码设置为当前网站的默认编码 java类: import java.io.IOException; import javax.servlet.Filter; import ja ...
- 《Cracking the Coding Interview》——第18章:难题——题目10
2014-04-29 04:22 题目:给定一堆长度都相等的单词,和起点.终点两个单词,请从这堆单词中寻找一条变换路径,把起点词变成终点词,要求每次变换只能改一个字母. 解法:Leetcode中有Wo ...
- 《算法》C++代码 快速排序
快速排序,简称快排,常称QuickSort.QSort.在排序算法中非常常用,其编程复杂度低,时间复杂度O(NlogN),空间复杂度O(N),执行效率稳定,而且常数很低. 基本思想就是二分,例如你要将 ...
- linux统计分析流量-wireshark
wireshark是一款带界面的开源抓包工具,可以用来对系统流量进行统计分析. 安装 由于wireshark是带界面的,所以一般在界面环境下运行,可以通过yum安装: $ yum install -y ...
- 常用模块(sys)
import sys# sys.argv() # 命令参数List,第一个元素是程序本身路径,如:python test.py run db# sys.exit('shh') # 退出程序,正常退出时 ...
- QA 、 QC & QM软件测试入门专业名词解释 -- 灌水走起
灌水正式开始: 说明:我的农田,我灌水 一.QA . QC & QM: 1.QM QM 是quanlity management,中文名称是品质管理 2.QA QA是英文quality ass ...
- 【转载】Unity3D研究院之IOS&Andoird使用Sharesdk遇到的坑
这两天研究了一下ShareSDK,说实话挺好用的,但是还是有点坑的地方.那么雨松MOMO写下博文记录一下来我遇到的坑,嘿嘿. 大部分内容它的文档上已经说的很清楚了. http://wiki.share ...
- ASP.NET Core 2.1 源码学习之 Options[2]:IOptions 【转】
原文链接:https://www.cnblogs.com/RainingNight/p/strongly-typed-options-ioptions-in-asp-net-core.html 在 上 ...
- centos6系列问题
一.NetworkManager启动问题 1.由于以后要支持e1000版虚拟化网卡,所有centos6镜像均按照NetworkManager服务,并设置开机自启动 2.虚机启动时,默认是Network ...
- vmware中三种网络连接方式(复制)
原文来自http://note.youdao.com/share/web/file.html?id=236896997b6ffbaa8e0d92eacd13abbf&type=note 我怕链 ...