【题目】给定n行m列的矩阵,每个位置有一个指示方向(上下左右)或没有指示方向(任意选择),要求给未定格(没有指示方向的位置)确定方向,使得从任意一个开始走都可以都出矩阵,求方案数。n,m<=200,k<=300(未定格数量)。

【算法】生成树计数(矩阵树定理)

【题解】先对定向格DFS找环判断是否无解。

然后每个点向指示方向连边,未定格向四周连边,外界作为一个点。

将所有有向边反向后,就是求根为外界的树形图的数量,生成树计数问题用矩阵树定理解决。

复杂度T*O((n*m)^3)。

考虑优化,发现重要的只有未定格的方向且k很小,所以将未定格之间的路径直接计算后只保留未定格的图,再用矩阵树定理解决。

复杂度T*O(k^3)。

注意:

1.逆元的log放在外面,否则复杂度会变成O(k^3*log k)。

2.因为要取模,高斯消元前必须全部变成正数,且矩阵每次交换两行都会使答案取反。

3.有重边,邻接矩阵不能赋值为1,有向边度数矩阵只计算入度。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,MOD=1e9+;
const int fx[]={,,,-};
const int fy[]={,-,,};
struct edge{int v,from;}e[maxn*];
struct node{int x,y;}b[maxn];
int n,m,vis[maxn][maxn],v[maxn][maxn],tot,t[maxn][maxn],a[maxn][maxn];
char s[maxn];
bool ok;
void dfs(node u,int mark){
if(v[u.x][u.y]||u.x<||u.x>n||u.y<||u.y>m)return;
vis[u.x][u.y]=mark;
int X=u.x+fx[t[u.x][u.y]],Y=u.y+fy[t[u.x][u.y]];
if(vis[X][Y]==mark)ok=;
else if(vis[X][Y])return;
else dfs((node){X,Y},mark);
}
void insert(int u,int v){
a[v][v]++;a[u][v]--;//
}
void gcd(int a,int b,int& x,int& y){
if(!b){x=;y=;}
else{gcd(b,a%b,y,x);y-=x*(a/b);}
}
int inv(int a){
int x,y;
gcd(a,MOD,x,y);
return (x%MOD+MOD)%MOD;
}
int gauss(int n){
bool f=;
for(int i=;i<=n;i++)for(int j=;j<=n;j++)a[i][j]=(a[i][j]+MOD)%MOD;
for(int i=;i<=n;i++){
int r=i;
for(int j=i+;j<=n;j++)if(a[j][i]>a[r][i])r=j;
if(r!=i){for(int j=i;j<=n+;j++)swap(a[i][j],a[r][j]);f^=;}
int w=inv(a[i][i]);//
for(int j=i+;j<=n;j++){
for(int k=n+;k>=i;k--){
a[j][k]=(a[j][k]-1ll*a[j][i]*w%MOD*a[i][k]%MOD+MOD)%MOD;//
}
}
}
int ans=f?MOD-:;
for(int i=;i<=n;i++)ans=1ll*ans*a[i][i]%MOD;
return ans;//
}
int main(){
int T;scanf("%d",&T);
while(T--){
memset(v,,sizeof(v));
memset(vis,,sizeof(vis));
memset(a,,sizeof(a));
tot=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=m;j++){
if(s[j]=='U')t[i][j]=;
if(s[j]=='D')t[i][j]=;
if(s[j]=='L')t[i][j]=;
if(s[j]=='R')t[i][j]=;
if(s[j]=='.'){v[i][j]=++tot;b[tot]=(node){i,j};}
}
}
ok=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++)if(!vis[i][j])dfs((node){i,j},(i-)*m+j);
if(!ok)break;
}
if(!ok){puts("");continue;}
tot++;
for(int i=;i<tot;i++){
int x=b[i].x,y=b[i].y;
for(int j=;j<;j++){
int X=x+fx[j],Y=y+fy[j];bool yes=;
while(X>=&&X<=n&&Y>=&&Y<=m){
if(v[X][Y]){if(v[X][Y]!=i)insert(v[X][Y],i);yes=;break;}
else{
int o1=fx[t[X][Y]],o2=fy[t[X][Y]];
X+=o1;Y+=o2;
}
}
if(!yes)insert(tot,i);
}
}
printf("%d\n",gauss(tot-));
}
return ;
}

【LibreOJ】#6259. 「CodePlus 2017 12 月赛」白金元首与独舞的更多相关文章

  1. [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞

    [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...

  2. 「CodePlus 2017 12 月赛」白金元首与独舞

    description 题面 data range \[ 1 \leq T \leq 10, 1 \leq n, m \leq 200 , 0 \leq k \leq \min(nm, 300)\] ...

  3. 走进矩阵树定理--「CodePlus 2017 12 月赛」白金元首与独舞

    n,m<=200,n*m的方阵,有ULRD表示在这个格子时下一步要走到哪里,有一些待决策的格子用.表示,可以填ULRD任意一个,问有多少种填法使得从每个格子出发都能走出这个方阵,答案取模.保证未 ...

  4. loj6259「CodePlus 2017 12 月赛」白金元首与独舞

    分析 我们将没连的点连向周围四个点 其余的按照给定的方向连 我们将所有连出去的位置统一连到0点上 再以0作为树根 于是就将问题转化为了有向图内向树计数 代码 #include<iostream& ...

  5. 【LIbreOJ】#6256. 「CodePlus 2017 12 月赛」可做题1

    [题意]定义一个n阶正方形矩阵为“巧妙的”当且仅当:任意选择其中n个不同行列的数字之和相同. 给定n*m的矩阵,T次询问以(x,y)为左上角的k阶矩阵是否巧妙.n,m<=500,T<=10 ...

  6. 【LibreOJ】#6257. 「CodePlus 2017 12 月赛」可做题2

    [题意]数列满足an=an-1+an-2,n>=3.现在a1=i,a2=[l,r],要求满足ak%p=m的整数a2有多少个.10^18. [算法]数论(扩欧)+矩阵快速幂 [题解]定义fib(i ...

  7. 「CodePlus 2017 12 月赛」火锅盛宴(模拟+树状数组)

    1A,拿来练手的好题 用一个优先队列按煮熟时间从小到大排序,被煮熟了就弹出来. 用n个vector维护每种食物的煮熟时间,显然是有序的. 用树状数组维护每种煮熟食物的数量. 每次操作前把优先队列里煮熟 ...

  8. 「CodePlus 2017 12 月赛」可做题2(矩阵快速幂+exgcd+二分)

    昨天这题死活调不出来结果是一个地方没取模,凉凉. 首先有个一眼就能看出来的规律... 斐波那契数列满足$a_1, a_2, a_1+a_2, a_1+2a_2, 2a_1+3a_2, 3a_1+5a_ ...

  9. 「CodePlus 2017 12 月赛」火锅盛宴

    n<=100000种食物,给每个食物煮熟时间,有q<=500000个操作:在某时刻插入某个食物:查询熟食中编号最小的并删除之:查询是否有编号为id的食物,如果有查询是否有编号为id的熟食, ...

随机推荐

  1. C++ Primer Plus学习:第四章

    C++入门第四章:复合类型 1 数组 数组(array)是一种数据格式,能够存储多个同类型的值. 使用数组前,首先要声明.声明包括三个方面: 存储每个元素中值的类型 数组名 数组中的元素个数 声明的通 ...

  2. 【leetcode】215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  3. Sass & Scss & CSS3

    Sass & Scss & CSS3 Sass & Scss @mixin & @include & @import & variable https: ...

  4. 25个Java机器学习工具&库--转载

    本列表总结了25个Java机器学习工具&库: 1. Weka集成了数据挖掘工作的机器学习算法.这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用.Weka包括一系列的工具,如数据预 ...

  5. android面试(1)----布局

    1.说出android 五中布局,并说出各自作用? FrameLayout: 堆叠布局,也是就可以堆在一起.最长应用于Fragment的使用上. LinearLayout: 线性布局,可以是竖排或水平 ...

  6. Codeforces710

    [未完待续] A The only king stands on the standard chess board. You are given his position in format &quo ...

  7. 【Python3的命名空间与作用域,闭包函数,装饰器】

    一.命名空间与作用域 命名空间是名字和对象的映射,就像是字典,key是变量名,value是变量的值 1.命名空间的定义 name='egon' #定义变量 def func(): #定义函数 pass ...

  8. 开放接口/RESTful/Api服务的设计和安全方案

    总体思路 这个涉及到两个方面问题:一个是接口访问认证问题,主要解决谁可以使用接口(用户登录验证.来路验证)一个是数据数据传输安全,主要解决接口数据被监听(HTTPS安全传输.敏感内容加密.数字签名) ...

  9. 【bzoj2938】病毒

    Portal -->bzoj2938 Solution 这题的话..一开始想的是不是上一个trie就消失了但是后来发现好像我还是太年轻qwq 比较容易联想到..AC自动机,多串匹配嘛 然后就.. ...

  10. 【bzoj2402】陶陶的难题II

    Portal -->bzoj2402 Solution 这题的话,看到答案的形式想到分数规划(Portal -->[learning]) 套路一波,记当前二分的\(mid\)为\(\lam ...