• BZOJ4031 [HEOI2015]小Z的房间


    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    题目链接:BZOJ4031

    正解:矩阵树定理+高斯消元

    解题报告:

      矩阵树定理裸题,建图之后跑高斯消元。

      但是这道题比较特殊,取模取得是$10^9$,如果不用取模直接用$double$,取模质数的话就可以乘逆元,

      如果不是质数可能没有逆元,那么我们考虑我们的目的是要让之后的每一项的这一位都变成$0$,正好满足辗转相除法的最终结果,所以跑一遍辗转相除法就可以避开没有逆元的尴尬问题了。

      注意行列式交换一次会导致结果变号,所以记录一下,最后可能要取相反数。

    //It is made by ljh2000
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    #include <bitset>
    using namespace std;
    typedef long long LL;
    typedef complex<double> C;
    const double pi = acos(-1);
    const int MAXN = 12;
    const int maxn = 100;
    const int mod = 1000000000;
    int n,m,cnt,b[MAXN][MAXN],D[maxn][maxn],G[maxn][maxn];//D:度数矩阵  G:邻接矩阵
    LL a[maxn][maxn],ans;
    char ch[MAXN][MAXN];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void link(int x,int y){
    	G[x][y]=1;
    	D[x][x]++;
    }
    
    inline void Gauss(){
    	ans=1; int f=1;
    	for(int i=1;i<cnt;i++) {
    		for(int j=i+1;j<cnt;j++) {
    			LL x=a[i][i],y=a[j][i];
    			while(y) {
    				LL t=x/y; x%=y; swap(x,y);
    				for(int k=i;k<cnt;k++)
    					a[i][k]=(a[i][k]-t*a[j][k]%mod+mod)%mod;
    				for(int k=i;k<cnt;k++)
    					swap(a[i][k],a[j][k]);
    				f=-f;
    			}
    		}
    		if(a[i][i]==0) { ans=0; return ; }
    		ans=ans*a[i][i]%mod;
    	}
    
    	if(f==-1) ans=(mod-ans)%mod;
    }
    
    inline void work(){
    	n=getint(); m=getint(); int nowx,nowy;
    	for(int i=1;i<=n;i++) scanf("%s",ch[i]+1);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			if(ch[i][j]=='.')
    				b[i][j]=++cnt;
    
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++) {
    			if(ch[i][j]=='*') continue;
    			for(int k=0;k<4;k++) {
    				nowx=i+dx[k]; nowy=j+dy[k];
    				if(nowx<=0 || nowy<=0 || nowx>n || nowy>m || ch[nowx][nowy]=='*') continue;
    				link(b[i][j],b[nowx][nowy]);
    			}
    		}
    
    	for(int i=1;i<=cnt;i++)
    		for(int j=1;j<=cnt;j++)
    			a[i][j]=D[i][j]-G[i][j],a[i][j]+=mod,a[i][j]%=mod;
    
    	Gauss();
    
    	printf("%lld",ans);
    }
    
    int main()
    {
        work();
        return 0;
    }
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    

      

  • 相关阅读:
    C# 图片处理(添加水印 & 原尺寸压缩 & 等比缩放 & 创建缩略图)
    Quill中文文档及基本使用
    2015年 阿里2道前端笔试题+堆糖2道前端笔试题
    Guava Ordering , table BiMap Multimap RangeMap (Map的骚操作)
    9条消除if...else的锦囊妙计,助你写出更优雅的代码 (转) 主要是设计模式
    Docker容器性能监控工具google/cadvisor
    双重检查锁的漏洞 volatile 指令进行重排
    java使用AES加密解密 AES128ECB加密
    Hutool——国产良心工具包, 加密,身份证处理
    浏览器解析工具UserAgentUtils
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6523940.html
Copyright © 2020-2023  润新知