zoukankan      html  css  js  c++  java
  • BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )

    把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 

    ---------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
     
    const int MOD = 45989;
    const int maxn = 29;
    const int maxm = 129;
     
    int N, M, T, A, B;
    int U[maxm], V[maxm], Id[maxm], f[maxm];
     
    struct matrix {
    int a[maxm][maxm];
    matrix() {
    memset(a, 0, sizeof a);
    }
    matrix operator * (const matrix &o) const {
    matrix ret;
    for(int i = 0; i < M; i++)
    for(int k = 0; k < M; k++)
    for(int j = 0; j < M; j++)
    (ret.a[i][j] += a[i][k] * o.a[k][j]) %= MOD;
    return ret;
    }
    matrix operator = (const matrix &o) {
    memcpy(a, o.a, sizeof a);
    return *this;
    }
    void Unit() {
    for(int i = 0; i < M; i++)
    a[i][i] = 1;
    }
    } mat, base;
     
    void init() {
    scanf("%d%d%d%d%d", &N, &M, &T, &A, &B);
    for(int i = 0; i < M; i++) {
    scanf("%d%d", U + i, V + i);
    U[i + M] = V[i];
    V[i + M] = U[i];
    Id[i] = Id[i + M] = i;
    }
    }
     
    int main() {
    init();
    M <<= 1;
    for(int i = 0; i < M; i++)
    for(int j = 0; j < M; j++)
    if(Id[i] != Id[j] && V[i] == U[j]) base.a[j][i] = 1;
    mat.Unit();
    for(T--; T; T >>= 1, base = base * base)
    if(T & 1) mat = mat * base;
    memset(f, 0, sizeof f);
    for(int i = 0; i < M; i++)
    if(U[i] == A) f[i] = 1;
    int ans = 0;
    for(int i = 0; i < M; i++) if(V[i] == B)
    for(int j = 0; j < M; j++)
    if((ans += mat.a[i][j] * f[j]) >= MOD) ans -= MOD;
    printf("%d ", ans);
    return 0;
    } 

    ---------------------------------------------------------------------------------------------

    1875: [SDOI2009]HH去散步

    Time Limit: 20 Sec  Memory Limit: 64 MB
    Submit: 1027  Solved: 469
    [Submit][Status][Discuss]

    Description

    HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

    Input

    第一行:五个整数N,M,t,A,B。其中N表示学校里的路口的个数,M表示学校里的 路的条数,t表示HH想要散步的距离,A表示散步的出发点,而B则表示散步的终点。 接下来M行,每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。数据保证Ai = Bi,但 不保证任意两个路口之间至多只有一条路相连接。 路口编号从0到N − 1。 同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 答案模45989。

    Output

    一行,表示答案。

    Sample Input

    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2

    Sample Output

    4

    HINT

    对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。
    对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 230,0 ≤ A,B

    Source

  • 相关阅读:
    ansible
    爬虫框架之scrapy
    Mongodb
    xml 创建 添加节点或属性(自定义,复制)
    web站点崩溃的原因总结
    C# 关闭正在执行的文件
    254. Factor Combinations
    256. Paint House
    156. Binary Tree Upside Down
    170. Two Sum III
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4977495.html
Copyright © 2011-2022 走看看