BZOJ4887可乐题解--矩阵运算

题目链接

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 不知道怎么回事

然后在8.15发现是矩阵数组没清空....现已AC

代码

#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){memet(mat,0,sizeof(mat));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;
}
posted @ 2018-07-16 20:42  Rye_Catcher  阅读(150)  评论(0编辑  收藏  举报