http://www.lydsy.com/JudgeOnline/problem.php?id=2467

题意:

思路:
要用矩阵树定理不难,但是这里的话需要取模,所以是需要计算逆元的,但是用辗转相减会更简单。

引用一大神博客里的介绍:http://blog.csdn.net/u013010295/article/details/47451451

值得一提的是,有些题目要求行列式模上一个数的结果。怎么求模意义下的行列式呢?这些题答案都比较大,用浮点数的话精度达不到要求,确实是一个问题。(显然强行用高精度分数类直接消元,最后再取模是可以的,但实现起来就复杂了)

我们注意到最后行列式是主对角线上的元素乘积再取模,根据同余定理,我们只需要对这些元素取模后的结果再相乘,就能得到相同的结果。因此我们可以采用在模意义下对矩阵消元的方法。然而消元过程中我们不可避免地要计算当前列的主元间的比值,这要用到除法;但另一方面,只有加法、减法、乘法操作才能保证同余,怎么在带有除法操作的条件下取模呢?

如果模的数是个质数(其实只需要模数和除数互质),对于除法我们可以直接变成乘上除数的逆元,根据费马小定理,这个逆元可以用快速幂简单求出来。如果模数不是质数,这就比较复杂了,我们在此介绍一种简单的方法。

我们知道,如果对于两个正数,不断地把较大的数减去较小的数,最后一定会有一个数为0。你可能已经知道,这就是辗转相减法的过程。同样地,我们对于矩阵中的两行,不断地把主元较大的那一行减去主元较小的那一行,最终一定有一行主元为0,也就是完成了消元(注意这里的减法是模意义下的减法)。而且这一过程是不改变行列式的。

(需要说明的是,一般情况下,矩阵中可能会有主元为负数的情况,这时我们简单的“大数减小数”显然是不行了。你可能会想到,要对正负数的各种情况判断一下,分别改为加法和减法操作。然而,这里我们讨论的是模意义下的矩阵消元,矩阵的元素都是正整数,并不存在这个问题。)

这样的减法效率还不够高,显然,如果两个主元相差太大,我们需要不断地用一行减去另一行。我们可以记录下两个主元相除的商x(这里用的是整数除法,当不能整除的时候向上向下取整都可以,由于计算机内部的整数除法实现,我们一般是向下取整,而且也符合我们取商的直觉,下面复杂度计算的是向下取整的做法),一次性用主元较大的行减去主元较小的行乘上x倍,这样效率就大大提高了。我们这样做的复杂度是多少呢?其实你也许已经发现,这一过程实际上就是辗转相除法,所以时间复杂度是O(log(n))的。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n;
int C[maxn][maxn]; int Gauss()
{ for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
C[i][j]=(C[i][j]+)%; int ans=;
for(int i=;i<=n;i++) //当前行
{
for(int j=i+;j<=n;j++) //当前行之后的每一行
{
while(C[j][i]) //利用gcd的方法,不停地进行辗转相除
{
int tmp=C[i][i]/C[j][i];
for(int k=i;k<=n;k++) C[i][k]=(C[i][k]-tmp*C[j][k])%;
for(int k=i;k<=n;k++) swap(C[i][k],C[j][k]);
ans=-ans;
}
}
if(C[i][i]==) return ;
ans=(ans*C[i][i])%;
}
ans=(ans+)%;
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
memset(C,,sizeof(C));
scanf("%d",&n); int cnt=n;
for(int i=;i<=n;i++)
{
C[i][i]+=;
C[i][i%n+]+=-;
C[i][(i-)>=?i-:n]+=-;
}
for(int i=;i<=n;i++)
{
cnt++;
C[i][cnt]=C[cnt][i]+=-;
C[cnt][cnt]+=;
C[cnt][cnt+]+=-;
C[cnt+][cnt]+=-; cnt++;
C[cnt][cnt]+=;
C[cnt][cnt+]+=-;
C[cnt+][cnt]+=-; cnt++;
C[cnt][cnt]+=;
C[cnt][i%n+]+=-;
C[(i+)<=n?i+:][cnt]+=-;
}
n=cnt-;
printf("%d\n",Gauss());
}
return ;
}

BZOJ 2467: [中山市选2010]生成树(矩阵树定理+取模高斯消元)的更多相关文章

  1. 【bzoj2467】[中山市选2010]生成树 矩阵树定理

    题目描述 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成的圈.在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形.这些五角形只在五角形圈的中心的圈 ...

  2. BZOJ 2467: [中山市选2010]生成树 [组合计数]

    2467: [中山市选2010]生成树 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 638  Solved: 453[Submit][Status][ ...

  3. BZOJ 2467: [中山市选2010]生成树

    有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成的圈.在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形.这些五角形只在五角形圈的中心的圈上有公共的 ...

  4. BZOJ 2467 [中山市选2010]生成树(组合数学)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2467 [题目大意] 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边 ...

  5. BZOJ_2467_[中山市选2010]生成树_数学

    BZOJ_2467_[中山市选2010]生成树_数学 [Submit][Status][Discuss] Description 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成 ...

  6. bzoj 4031: 小Z的房间 矩阵树定理

    bzoj 4031: 小Z的房间 矩阵树定理 题目: 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时 ...

  7. 2019.01.02 bzoj2467: [中山市选2010]生成树(矩阵树定理)

    传送门 矩阵树定理模板题. 题意简述:自己看题面吧太简单懒得写了 直接构建出这4n4n4n个点然后按照题面连边之后跑矩阵树即可. 代码: #include<bits/stdc++.h> # ...

  8. [bzoj2467][中山市选2010]生成树_快速幂

    生成树 bzoj-2467 中山市选2010 题目大意:题目链接 注释:略. 想法:首先,考虑生成树的性质.每两个点之间有且只有一条路径.我们将每个五边形的5条边分为外面的4条边和内部的一条边,在此简 ...

  9. bzoj 2468: [中山市选2010]三核苷酸

    2468: [中山市选2010]三核苷酸 Description 三核苷酸是组成DNA序列的基本片段.具体来说,核苷酸一共有4种,分别用’A’,’G’,’C’,’T’来表示.而三核苷酸就是由3个核苷酸 ...

随机推荐

  1. 十天精通CSS3(1)

    什么是CSS3? CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大的新功能. 目前主流浏览器chrome.safari.firefox.opera.甚至360都已经支 ...

  2. [py]GIL(全局解释器锁):多线程模式

    在多线程 时同一时刻只允许一个线程来访问CPU,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL 参考 Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务.多个P ...

  3. (转)从零开始的Spring Session(一)

    Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...

  4. 摄影EV值深入研究

    1. 什么是EV值 1.1. EV值定义 EV(Exposure Value),曝光值,是反应曝光量的一个值.当感光度为ISO 100.光圈值为F1.曝光时间为1秒时,定义曝光量为0.曝光量减少一档时 ...

  5. 几乎考虑到了每个细节的php图片上传

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> < ...

  6. 2:5 视图控制器result的配置

    result:   1:其实底层还是使用原来servlet的转发和重定向的方法: 2:redirectAction:只能定位到 action (比如下面name属性为 *User 的Action ,但 ...

  7. VueJS 数据驱动和依赖追踪分析

    之前关于 Vue 数据绑定原理的一点分析,最近需要回顾,就顺便发到随笔上了 在之前实现一个自己的Mvvm中,用 setter 来观测model,将界面上所有的 viewModel 绑定到 model ...

  8. discuz财付通也阵亡了

    今日做交易部分,然后焦头烂额. 首先这积分,威望,金钱,什么鬼,乱七八糟的...... 然后这支付宝,啊,,,,,竟然停止个人接口了,不得已要使用财付通. %&……*&……&不 ...

  9. UVALive - 7269 I - Snake Carpet

    思路: 多画画就发现从五的时候可以这么填: 六的时候这么填: 七的时候这么填: 看出规律了吗? 没看出的话再画画把. #include <bits/stdc++.h> using name ...

  10. 形象易懂讲解算法I——小波变换

    https://zhuanlan.zhihu.com/p/22450818?refer=dong5 最早发于回答:能不能通俗的讲解下傅立叶分析和小波分析之间的关系? - 咚懂咚懂咚的回答现收入专栏. ...