ZOJ3874 Permutation Graph
Time Limit: 2 Seconds Memory Limit: 65536 KB
Edward has a permutation {a1, a2, … an}. He finds that if he connects each pair (ai, aj) such that i < j and ai > aj, he will get a graph.
For example, if the permutation is {2, 3, 1, 4}, then 1 and 2 are connected and 1 and 3 are connected.
Edward lost his permutation, but he does know the connected components of the corresponding graph. He wants to know how many permutations will result in the same connected components.
Note that two vertices u, v belong to the same connected component if there exists a sequence of vertices starting with u and ending with v such that every two subsequent vertices in the sequence are connected by an edge.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains two integers n, m (1 ≤ m ≤ n ≤ 100000), indicating the length of the permutation and the number of connected components in the graph.
Each of the following m lines contains an integer ci which denotes the size of i-th connected component, followed by ci distinct integers vi,1, vi,2, … vi,ci which denotes the connected component (1 ≤ ci, vi,1, vi,2, … vi,ci ≤ n).
It is guaranteed that every number will appear in exact one connected component and c1 + c2 + … + cm = n.
Output
For each case, output the answer modulo 786433.
Sample Input
2
4 4
1 1
1 2
1 3
1 4
4 2
3 1 2 3
1 4
Sample Output
1
3
Hint
For the second case, the three permutations is: {2, 3, 1, 4}, {3, 2, 1, 4}, {3, 1, 2, 4}.
Author: LIN, Xi
Source: The 12th Zhejiang Provincial Collegiate Programming Contest
动态规划 分治NTT优化
随意脑补一下可以发现构成连通块的数排序后一定是连续+1递增的一串,不然它们中肯定有数连到别的地方去。
设f[i]表示大小恰好为i的连通块的方案数首先列出一个简单粗暴的方程:
$ f[i]=\sum_{j=1}^{i} A_{j}^{j} * f[i-j] $
$ A_{j}^{j}=j!$
复杂度$O(n^2)$
注意到右边构成了一个卷积的形式,且每个f都只由比它小的f计算得到。
于是可以愉快地用分治NTT优化DP
(前置技能:CDQ分治)
分治NTT理解了以后其实挺简单的,利用CDQ分治计算整个序列,当处理一个区间时,该区间的前一半已经被算完了,只需要把前一半的项卷积一下,答案累加到下标对应的后一半位置去,如此递归分治即可。
注意NTT的数组空间要开到(mid-l+1)的两倍。刚开始想当然觉得for(N=1,len=0;N<=m;N<<=1)等价,实际上这样做的话N会停在某个比size大,比2*size小的2的幂上
786433的原根是10 ←不知为什么记成11,调了半天
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#define LL long long
using namespace std;
const int mod=;
const int G=;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
LL fac[mxn];
void init(){
fac[]=;
for(int i=;i<mxn;i++)fac[i]=(LL)fac[i-]*i%mod;
return;
}
LL ksm(LL a,LL k){
int res=;
while(k){
if(k&)res=(LL)res*a%mod;
a=(LL)a*a%mod;
k>>=;
}
return res;
}
LL a[mxn<<],b[mxn<<];
int N,len,rev[mxn<<];
void NTT(LL *a,int flag){
for(int i=;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=;i<N;i<<=){
int p=i<<;
LL gn=ksm(G,(flag==)?(mod-)/p:(mod-)-(mod-)/p);
for(int j=;j<N;j+=p){
LL g=;
for(int k=;k<i;k++,g=(LL)g*gn%mod){
LL x=a[j+k],y=g*a[j+k+i]%mod;
a[j+k]=(x+y)%mod;
a[j+k+i]=(x-y+mod)%mod;
}
}
}
if(flag==-){
LL INV=ksm(N,mod-);
for(int i=;i<N;i++)a[i]=(LL)a[i]*INV%mod;
}
return;
}
LL f[mxn];
void solve(int l,int r){
if(l==r){
f[l]=((fac[l]-f[l])%mod+mod)%mod;
//当l==r时,比l小的f全都算完了,可以得出f[l]=fac[l]-f[l]
return;
}
int i,j,mid=(l+r)>>;
solve(l,mid);//先算前一半
int m=(mid-l+)<<;//空间开两倍
for(N=,len=;N<=m;N<<=)len++;
for(i=;i<N;i++)rev[i]=(rev[i>>]>>)|((i&)<<(len-));
for(i=;i<N;i++)a[i]=b[i]=;
for(i=l;i<=mid;i++)//为了节省空间,将每一项左移l位计算
a[i-l]=f[i];
for(i=l;i<=r;i++)b[i-l]=fac[i-l];
//
NTT(a,);NTT(b,);
for(i=;i<N;i++)a[i]=(LL)a[i]*b[i]%mod;
NTT(a,-);
for(i=mid+;i<=r;i++){//将贡献累加到右半边
(f[i]+=a[i-l])%=mod;
}
solve(mid+,r);
return;
}
int n;
int num[mxn];
bool check(int x){
sort(num+,num+x+);
for(int i=;i<=x;i++){
if(num[i]!=num[i-]+)return ;
}
return ;
}
int main(){
int i,j;
init();
f[]=;
solve(,);
int T=read(),m;
while(T--){
n=read();m=read();
bool flag=;
LL ans=;
for(i=;i<=m;i++){
int sz=read();
for(j=;j<=sz;j++)num[j]=read();
if(!check(sz))flag=;
ans=(ans*f[sz])%mod;
}
if(!flag)puts("");
else printf("%lld\n",ans);
}
return ;
}
ZOJ3874 Permutation Graph的更多相关文章
- ZOJ3874 Permutation Graph 【分治NTT】
题目链接 ZOJ3874 题意简述: 在一个序列中,两点间如果有边,当且仅当两点为逆序对 给定一个序列的联通情况,求方案数对\(786433\)取模 题解 自己弄了一个晚上终于弄出来了 首先\(yy\ ...
- ZOJ3874 Permutation Graph(NTT&&cdq分治)
最近在看几道整体二分还有cdq分治的东西,突然间想起前几个礼拜的ZOJ题,然后看了一下代码,经过了一些深思熟虑之后,发现自己终于看懂了,下面就用别人的代码来剖析一下整个解题的思路吧,具体的内容我再看看 ...
- ZOJ 3874 Permutation Graph 分治NTT
Permutation Graph Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has a permutation {a1, a2 ...
- ZOJ 3874 Permutation Graph ——分治 NTT
发现每一块一定是按照一定的顺序的. 然后与标号无关,并且相同大小的对答案的影响相同. 然后列出递推式,上NTT+分治就可以了. 然后就可以与输入同阶处理答案了. #include <map> ...
- ZOJ 3874 Permutation Graph (分治NTT优化DP)
题面:vjudge传送门 ZOJ传送门 题目大意:给你一个排列,如果两个数构成了逆序对,就在他们之间连一条无向边,这样很多数会构成一个联通块.现在给出联通块内点的编号,求所有可能的排列数 推来推去容易 ...
- 140 - The 12th Zhejiang Provincial Collegiate Programming Contest(第二部分)
Floor Function Time Limit: 10 Seconds Memory Limit: 65536 KB a, b, c and d are all positive int ...
- Codeforces Round #198 (Div. 2) D. Bubble Sort Graph (转化为最长非降子序列)
D. Bubble Sort Graph time limit per test 1 second memory limit per test 256 megabytes input standard ...
- codeforces 340D Bubble Sort Graph(dp,LIS)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Bubble Sort Graph Iahub recently has lea ...
- 2017ICPC南宁赛区网络赛 Minimum Distance in a Star Graph (bfs)
In this problem, we will define a graph called star graph, and the question is to find the minimum d ...
随机推荐
- Android 平台 HTTP网速测试 案例 API 分析
作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/25996817 工信部规定的网速测试标准 : 除普通网页测速 ...
- DAY7敏捷冲刺
站立式会议 工作安排 (1)服务器配置 服务器端项目结构调整 (2)数据库配置 单词学习记录+用户信息 (3)客户端 客户端项目结构调整,代码功能分离 燃尽图 燃尽图有误,已重新修改,先贴卡片的界面, ...
- iOS开发跳转指定页面
for (UIViewController *VC in self.navigationController.viewControllers) { if ([VC isKindOfClass:[Car ...
- TCP系列26—重传—16、重组包
一.介绍 在TCP重传的时候,并没有限制TCP只能重传与初传完全相同的报文段大小,TCP允许执行重组包(repacketization),发送一个更大的TCP报文段,进而增加性能.TCP在重传时候允许 ...
- phpcms黄页,不能选择行业。解决办法
用phpcms黄页模块,发布产品的时候.不能选择 产品分类,点开之后,啥都没有,是空的. 这个是因为:js的问题. 解决办法:将 网站根目录的 js 文件中的两个文件,更换为 官方的两个js文件.即可 ...
- mysql 重置 root 密码
mysqld_safe --skip-grant-tables & UPDATE mysql.user SET authentication_string=PASSWORD('mima') W ...
- 【Python】Python中的引用和赋值
本文转自:http://my.oschina.net/leejun2005/blog/145911 在 python 中赋值语句总是建立对象的引用值,而不是复制对象.因此,python 变量更像是指针 ...
- 【Python】python文件名和文件路径操作
Readme: 在日常工作中,我们常常涉及到有关文件名和文件路径的操作,在python里的os标准模块为我们提供了文件操作的各类函数,本文将分别介绍“获得当前路径”“获得当前路径下的所有文件和文件夹, ...
- 【bzoj3312】[Usaco2013 Nov]No Change 状态压缩dp+二分
题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...
- 【bzoj1617】[Usaco2008 Mar]River Crossing渡河问题 dp
题目描述 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木 ...