[TJOI2017][BZOJ4887]可乐 解题报告

传送门:戳我qwq

首先先介绍一个性质,一张图的邻接矩阵的n次方后得到,矩阵A,A(i,j)表示在图中从 i 节点出发走了 n 步,到达 j 节点的可能方案数。这里不加证明,读者可以联系矩阵乘法的性质模拟一下。

我们考虑到机器人有爆炸的可能性,且爆炸后不能继续走动,且它可以待在原地不动。

那么不难想到,待在原地不动的情况可以用自环来解决。

机器人在任何一步都可能爆炸,机器人爆炸后,该状态将不对其他任何状态产生影响。

应该有读者已经想到了,我们可以把所有点都连向一个新建的节点,且该节点没有出度,机器人爆炸实际上就相当于被发配边疆且永远不能回来(雾。

既然已经考虑清楚,那么我们只需要对原始领接矩阵S进行改动,所有S[i][0]=1 ,S[i][i]=1 。

然后按照文章开头介绍的性质,A=S^t。A就是我们的答案矩阵。

机器人从1号节点出发,那么我们最终的答案就等于 。

于是我的代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline void read(int &x)
{
    x=0;int f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x*=f;
}
int N;
struct node{
    int max[35][35];
    friend node operator * (node a,node b)
    {
        node c;
        for(int i=0;i<=N;i++)
            for(int j=0;j<=N;j++)
                c.max[i][j]=0;
        for(int i=0;i<=N;i++)
        {
            for(int j=0;j<=N;j++)
            {
                for(int k=0;k<=N;k++)
                {
                    c.max[i][j]+=a.max[i][k]*b.max[k][j]%2017;
                    c.max[i][j]%=2017;
                }
            }
        }
        return c;
    }
};
int M,t;
node qpow(node st,int t)
{
    node base=st,ans;
    for(int i=0;i<=N;i++)
        for(int j=0;j<=N;j++)
            ans.max[i][j]=0;
    for(int i=0;i<=N;i++)
        ans.max[i][i]=1;
    while(t)
    {
        if(t&1)
            ans=ans*base;
        base=base*base;
        t>>=1;
    }
    return ans;
}
int main()
{
    read(N);read(M);
    node st;
    for(int i=0;i<=N;i++)
        for(int j=0;j<=N;j++)
            st.max[i][j]=0;
    int u,v;
    for(int i=1;i<=M;i++)
    {
        read(u);read(v);
        st.max[u][v]=1;
        st.max[v][u]=1;
    }
    read(t);
    for(int i=1;i<=N;i++)
        st.max[i][0]=1;
    for(int i=0;i<=N;i++)
        st.max[i][i]=1;
    node ans=qpow(st,t);
    int tot=0;
    for(int i=0;i<=N;i++)
    {
        tot+=ans.max[1][i];
        tot%=2017;
    }
    printf("%d\n",tot);
}
View Code

 

posted @ 2018-10-16 16:41  溡沭  阅读(165)  评论(0编辑  收藏  举报