zoukankan      html  css  js  c++  java
  • bzoj1875 [SDOI2009]HH去散步

    bzoj1875 [SDOI2009]HH去散步


    原题链接


    题解

    如果没有边方面的限制这就是道矩乘大水题。。。
    然而有
    所以考虑边->点,统计一条边走向另一条边的方案。
    把无向边拆成两条有向边,枚举点,再枚举终点是他的边,再枚举起点是他的边。。。
    就可以了,再把矩阵变成(t-1)次方,枚举起点的边终点的边统计答案。


    Code

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #define Fname "bzoj1875"
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    #define mod 45989
    typedef long long ll;
    il ll gi(){
        rg ll x=0;rg char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x;
    }
    int n,m;
    struct Mat{
        ll s[122][122];
        Mat(){rep(i,1,m)rep(j,1,m)s[i][j]=0;}
    };
    il vd Add(ll&a,ll b){a=(a+b)%mod;}
    Mat operator +(Mat a,Mat b){
        rep(i,1,m)rep(j,1,m)Add(a.s[i][j],b.s[i][j]);
        return a;
    }
    Mat operator *(Mat a,Mat b){
        Mat ret;
        rep(i,1,m)rep(j,1,m)rep(l,1,m)Add(ret.s[i][j],a.s[i][l]*b.s[l][j]%mod);
        return ret;
    }
    vd operator +=(Mat&a,Mat b){a=a+b;}
    vd operator *=(Mat&a,Mat b){a=a*b;}
    Mat operator ^(Mat a,ll b){
        Mat ret=a;--b;
        while(b){
        if(b&1)ret*=a;
        a*=a,b>>=1;
        }return ret;
    }
    vd operator ^=(Mat&a,ll b){a=a^b;}
    namespace e{
        int id=0,fir[51],nxt[121],dis[121];
        il vd add(int a,int b){nxt[++id]=fir[a],fir[a]=id,dis[id]=b;}
    }
    #define rev(o) ((o)&1?(o)+1:(o)-1)
    int main(){
        // freopen(Fname".in","r",stdin);
        // freopen(Fname".out","w",stdout);
        n=gi(),m=gi();
        ll t=gi();
        int S=gi()+1,T=gi()+1,a,b;
        using namespace e;
        rep(i,1,m)a=gi()+1,b=gi()+1,add(a,b),add(b,a);
        m<<=1;
        Mat s;
        rep(i,1,n)erep(x,i)erep(y,i)if(x!=y)s.s[rev(y)][x]=s.s[rev(x)][y]=1;
        s^=t-1;
        ll ans=0;
        erep(i,S)erep(j,T)Add(ans,s.s[i][rev(j)]);
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2
    */
    

    PS.常数优化真TM逼了狗。。。把ll mod=45989改成#define mod 45989就50->100
  • 相关阅读:
    什么是评审
    缺陷识别与缺陷跟踪
    白盒测试用例设计
    黑盒测试用例设计(二)
    黑盒测试用例设计技术
    Mysql基础
    JS函数
    SpringBoot整合JPA
    Python中的保留字
    操作系统的发展史
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7503331.html
Copyright © 2011-2022 走看看