题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=4887
分析
话说这道题经常见到类似模型来计数算期望,概率啊,然而我太蒻了都不会做,今天看到这题的第一个题解感觉真妙啊
我们构建邻接矩阵$A$,$a[i][j]=1$表示i到j状态有连接的边。
如果有一条边连接$u,v$则$a[u][v]=1$且$a[v][u]=1$
$a[i][i]=1$表示停在原地
再构建一个虚点0,$a[i][0]=1$表示自爆事件,完美满足题目要求
统计$\sum_{i=0}^{N}A[1][i]$就是答案
然而这题BZOJ AC 洛谷 WA 不知道怎么回事
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cctype> #include <cmath> #include <vector> #define ll long long #define ri register int using namespace std; const int maxn=35; const int maxm=105; const int inf=0x7ffffff; template <class T>inline void read(T &x){ x=0;int ne=0;char c; while(!isdigit(c=getchar()))ne=c=='-'; x=c-48; while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48; x=ne?-x:x; return ; } int n,m,t; struct Mat{ int mat[maxn][maxn]; Mat(){memset(mat,0,sizeof(mat));} Mat(int x){for(ri i=0;i<=n;i++)mat[i][i]=x;} Mat operator *(const Mat &b)const { Mat ans; for(ri i=0;i<=n;i++){ for(ri j=0;j<=n;j++){ for(ri k=0;k<=n;k++){ ans.mat[i][j]+=mat[i][k]*b.mat[k][j]%2017; } } } return ans; } Mat operator ^(const int & C)const { Mat ans=Mat(1),res=*this;int c=C; while(c){ if(c&1)ans=ans*res; res=res*res; c=c>>1; } return ans; } }a;
int main(){ int x,y,ans=0; read(n),read(m); for(ri i=0;i<=n;i++){ a.mat[i][0]=1; a.mat[i][i]=1; } for(ri i=1;i<=m;i++){ read(x),read(y); a.mat[x][y]=a.mat[y][x]=1; } read(t); a=a^t; for(ri i=0;i<=n;i++)ans+=a.mat[1][i]%2017; printf("%d\n",ans%2017); return 0; }
|