description

题面

data range

\[1 \leq T \leq 10, 1 \leq n, m \leq 200 , 0 \leq k \leq \min(nm, 300)
\]

solution

矩阵树定理

求无向图的生成树个数

度数矩阵-邻接矩阵

去掉一行一列求行列式

为了保证精度可以辗转相除

这里是模意义下的

const int mod=998244353;
int a[305][305];
il int gauss(int n){
RG int ans=1;
for(RG int i=2;i<=n;i++){
for(RG int j=i+1;j<=n;j++)
while(a[j][i]){
RG int t=a[i][i]/a[j][i];
for(RG int k=i;k<=n;k++)dec(a[i][k],1ll*t*a[j][k]%mod);
swap(a[i],a[j]);if(ans)ans=mod-ans;
}
ans=1ll*ans*a[i][i]%mod;
}
if(ans<0)ans+=mod;return ans;
}

有向图的外向(父亲指向儿子)生成树个数

对于每条边\((u,v)\),\(a[v][v]++,a[u][v]--\)(把度数看成入度)

然后直接求行列式即可

这题的解法

首先判掉无解

然后我们发现题目中每个空格方向的选择决定了空格之间的到达关系

于是这道题目变成了一个求内向生成树个数的题

套上矩阵树定理即可

code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=2000010;
const dd pi=acos(-1);
const int inf=2147483645;
const ll INF=1e18+1;
const ll P=100000;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} il void file(){
srand(time(NULL)+rand());
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
} int n,m,p[305][305],kx[305],ky[305];
int id[305][305],tag[305][305],t[100010],cnt,tot;
int a[305][305];
int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
il void init(){
memset(id,0,sizeof(id));
memset(tag,0,sizeof(tag));
memset(t,0,sizeof(t));
memset(a,0,sizeof(a));
n=read();m=read();tot=1;cnt=0;
for(RG int i=1,c;i<=n;i++)
for(RG int j=1;j<=m;j++){
a[i][j]=tag[i][j]=id[i][j]=c=0;
while(c!='L'&&c!='R'&&c!='U'&&c!='D'&&c!='.')c=getchar();
if(c=='L')p[i][j]=0;if(c=='R')p[i][j]=1;
if(c=='U')p[i][j]=2;if(c=='D')p[i][j]=3;
if(c=='.'){p[i][j]=4;id[i][j]=++tot;kx[tot]=i;ky[tot]=j;}
}
} il bool work(){
for(RG int i=1;i<=n;i++)
for(RG int j=1;j<=m;j++)
if(!id[i][j]&&!tag[i][j]){
RG int x=i,y=j,w=p[i][j];cnt++;
RG int xx=x+dx[w],yy=y+dy[w];
while(!id[x][y]&&!tag[x][y]&&x>0&&y>0&&x<=n&&y<=m){
tag[x][y]=cnt;x=xx;y=yy;w=p[x][y];xx=x+dx[w];yy=y+dy[w];
}
if(id[x][y])t[cnt]=id[x][y];
else if(x<1||y<1||x>n||y>m)t[cnt]=1;
else if(tag[x][y]==cnt)return 0;
else if(tag[x][y])t[cnt]=t[tag[x][y]];
}
return 1;
} il void upd(int &a,int b){a+=b;if(a>=mod)a-=mod;}
il void dec(int &a,int b){if(b)upd(a,mod-b);}
il int gauss(int n){
RG int ans=1;
for(RG int i=2;i<=n;i++){
for(RG int j=i+1;j<=n;j++)
while(a[j][i]){
RG int t=a[i][i]/a[j][i];
for(RG int k=i;k<=n;k++)dec(a[i][k],1ll*t*a[j][k]%mod);
swap(a[i],a[j]);if(ans)ans=mod-ans;
}
ans=1ll*ans*a[i][i]%mod;
}
if(ans<0)ans+=mod;return ans;
}
il int solve(){
for(RG int i=2;i<=tot;i++)
for(RG int w=0;w<=3;w++){
RG int xx=kx[i]+dx[w],yy=ky[i]+dy[w];
RG int u=t[tag[xx][yy]],v=i;
if(id[xx][yy])u=id[xx][yy];
if(xx<1||yy<1||xx>n||yy>m)u=1;
if(u==v||!u)continue;
a[v][v]++;if(!a[u][v])a[u][v]=mod;a[u][v]--;
}
return gauss(tot);
} int main()
{
RG int T=read();
while(T--){
init();
if(!work()){puts("0");continue;}
else printf("%d\n",solve());
}
return 0;
}

「CodePlus 2017 12 月赛」白金元首与独舞的更多相关文章

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

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

  2. 【LibreOJ】#6259. 「CodePlus 2017 12 月赛」白金元首与独舞

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

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

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

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

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

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

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

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

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

  7. 【LibreOJ】#6299. 「CodePlus 2018 3 月赛」白金元首与克劳德斯

    [题意]给出坐标系中n个矩形,类型1的矩形每单位时间向x轴正方向移动1个单位,类型2的矩形向y轴正方向,初始矩形不重叠,一个点被矩形覆盖当且仅当它在矩形内部(不含边界),求$(-\infty ,+\i ...

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

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

  9. 【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 ...

随机推荐

  1. 水灾 1000MS 64MB (广搜)

    水灾(sliker.cpp/c/pas) 1000MS  64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY ...

  2. android 学习六 构建用户界面和使用控件

    1.常用Android控件最终都会继承自View类 2.ViewGroup是一些布局类列表的基类,包括View和ViewGroup 3.构造界面的三种方法    a.完全使用代码(太灵活,而不好维护) ...

  3. CentOS 7.2静默安装Oracle11g

      Preface       Today I'm gonna export some test data to another server.The source server is Windows ...

  4. Qt-QML-自定义个自己的文本Text

    好久都没有正经的更新自己的文章了,这段时间也辞职了,听了小爱的,准备买个碗,自己当老板,下面请欣赏效果图 这个界面布局就是自己是在想不到啥了,按照常规汽车导航的布局布局了一下,主要看内容哈,看看这个文 ...

  5. Vs2015 遇到 CL:fatal error c1510 cannot load language clui.dll

    网上说什么点击修复VS,修改VS的,经验证都不好使,直接下载这个库,放在system32/64下面皆可以了

  6. eclipse格式化

    一.eclipse格式化的必要性 1.便于阅读 2.便于协作 二.eclipse格式化快捷键 ctrl shift + F

  7. JavaScript 作用域链范例

    函数在执行的过程中,先从自己内部找变量 如果找不到,再从创建当前函数所在的作用域去找,以此往上 注意找的是变量的当前状态 范例 例1 var a=1 function fn1() { function ...

  8. Python基础 之 tuple类-元组 和 dict类-字典

    tuple 元组 一.tuple 类的基本属性 1.元组,有序:元素不可被修改,不能被增加或者删除tuple类 tu = (111,22,33,44) 一般写元组的时候,推荐在最后加入,和类方法进行区 ...

  9. OpenMPI 集群配置

    现在有2台机器,希望可以尝试一下在多台机器上跑MPI的感觉,所以跑之前就得配置,先参考网址: https://www.cnblogs.com/awy-blog/p/3402949.html: 1. 配 ...

  10. python常用命令—‘\r’

    # \r 默认表示将输出的内容返回到第一个指针,这样的话,后面的内容会覆盖前面的内容 如常用的显示程序完成进度!!