2
10
2016
0

[BZOJ1875][SDOI2009]HH去散步[矩阵乘法]

看起来像个裸矩乘。。

但是题目中有这样一句话:

但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。

以点作为状态的算法很难处理这个条件,我们考虑以边作为状态。

只要在建矩阵的时候判断一下,不要从一条边直接走到它的反向边就可以了。

#include <iostream>
#include <cstring>
#include <cassert>
using namespace std;
typedef long long ll;
const int mod=45989;
struct matrix{
    int r,c;
    ll a[121][121];
    matrix(int r,int c){
        this->r=r;
        this->c=c;
        memset(a,0,sizeof(a));
    }
    ll * operator[](int p){
        return a[p];
    }
    matrix operator =(const matrix& rhs){
        //puts("WTF");
        assert(r==rhs.r && c==rhs.c);
        memcpy(a,rhs.a,sizeof(a));
        return *this;
    }
    matrix operator *(matrix& rhs){
        assert(c==rhs.r);
        //puts("WTF");
        matrix res(r,rhs.c);
        //puts("WTF");
        for(int i=0;i<r;i++)
            for(int j=0;j<rhs.c;j++)
                for(int k=0;k<c;k++)
                    (res[i][j]+=((a[i][k]*rhs[k][j])%mod))%=mod;
        //puts("WTF");
        return res;
    }
    matrix operator *=(matrix& rhs){
        return *this=(*this)*rhs;
    }
};
matrix power(const matrix& mat,ll b){
    //puts("WTF");
    matrix ret(mat.r,mat.c);
    matrix t(mat.r,mat.c);
    t=mat;
    //puts("line 48");
    for(int i=0;i<mat.r;i++)
        ret[i][i]=1;
    while(b){
        //puts("WTF");
        if (b%2)
            ret=ret*t;
        t=t*t;
        b/=2;
    }
    return ret;
}
struct edge{
    int from,to;
};
edge e[121];
int main(){
    int n,m,t,a,b;
    cin >> n >> m >> t >> a >> b;
    a++,b++;
    int cur=0;
    for(int i=1;i<=m;i++){
        int x,y;
        cin >> x >> y;
        x++,y++;
        e[cur++]=(edge){x,y};
        e[cur++]=(edge){y,x};
    }
    matrix mt(cur,cur);
    for(int i=0;i<cur;i++){
        for(int j=0;j<cur;j++){
            if (e[i].to==e[j].from && i!=(j^1))
                mt[i][j]++;
        }
    }
    mt=power(mt,t-1);
    int ans=0;
    for(int i=0;i<cur;i++)
        for(int j=0;j<cur;j++)
            if (e[i].from==a && e[j].to==b)
                (ans+=mt[i][j])%=mod;
    cout << ans;
}
Category: 未分类 | Tags: | Read Count: 933

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com