zoukankan      html  css  js  c++  java
  • [BZOJ2004] [Hnoi2010]Bus 公交线路

    [BZOJ2004] [Hnoi2010]Bus 公交线路

    \(n\)\(10^9\)了,还不矩阵吗?

    \(dp[S]\)表示前\(p\)位哪些点放了车并且要保证每个点都被经过了一次

    每次转移就是从前面的点里选一辆车跑过来,并且保证第一位没有车留下来

    状态\(2^{10}\)?

    不过状态显然保证\(popcount(S)==k\)

    状态最多其实是\(C_{10}^{5}=252\) 所以可以跑矩阵

    可能有点卡常,不过应该还可以优化,我没有加优化

     
    bool be;
     
    int n,p,k;
     
    int dp[1<<10];
    int cnt[1<<10];
    int tmp[1<<10];
    int A;
     
     
    int st[300],sc,id[1<<10];
    int f[1][300],ans[1][300];
     
     
    int B;
     
     
    struct Mat{
        int a[300][300];
        void init(){ memset(a,0,sizeof a); }
        void Get1(){ rep(i,1,sc) a[i][i]=1; }
        Mat operator * (const Mat x) const {
            Mat res;
            for(reg int i=1;i<=sc;++i) {
                for(reg int j=1;j<=sc;++j) {
                    ll t=0;
                    for(reg int o=1;o<=sc;++o) t+=a[i][o]*x.a[o][j];
                    res.a[i][j]=t%P;
                }
            }
            return res;
        }
    }res,x;
     
     
     
     
    void Solve(){
        A=(1<<p)-1;
        rep(i,1,A) cnt[i]=cnt[i&(i-1)]+1;
        rep(S,0,A) if(cnt[S]==k) ++sc,id[st[sc]=S]=sc;
        rep(S,0,A) if(cnt[S]==k) {
            if(S&1) {
                x.a[id[S]][id[(S>>1)|(1<<(p-1))]]++;
            } else {
                rep(i,0,p-1) if(S&(1<<i)) {
                    int NS=((S^(1<<i))>>1)|(1<<(p-1));
                    x.a[id[S]][id[NS]]++;
                }
            }
        }
        int T=0;
        for(reg int j=p-1;j>=p-k;j--) T|=1<<j;
        f[0][id[T]]=1;
        res.Get1();
        n-=k;
        int t=n;
        while(t) {
            if(t&1) res=res*x;
            x=x*x;
            t>>=1;
        }
        rep(i,0,0) rep(j,1,sc) rep(o,1,sc) (ans[i][o]+=f[i][j]*res.a[j][o])%=P;
        T=0;
        rep(j,p-k,p-1) T|=1<<j;
        printf("%d\n",ans[0][id[T]]);
    }
     
    bool ed;
     
    int main(){
        //printf("%.2lf\n",(&ed-&be)/1024.0/1024.0);
        n=rd(),k=rd(),p=rd();
        Solve();
    }
     
     
     
     
     
    
  • 相关阅读:
    Unity shader with lightmap
    清理数据库日志
    Sqlserver数据库还原一直显示“正在还原…”解决方法
    如何查看 SQL Server 执行的历史 SQL 语句记录?
    MYSQL 命令行大全 (简洁、明了、全面)
    C#Datatable导入sqlserver数据库中,三种常见,快捷的方法
    MongoDB下载页面
    等级保护和分级保护区别与联系
    等级保护和分级保护
    SQL2005EXPress自动备份
  • 原文地址:https://www.cnblogs.com/chasedeath/p/11665114.html
Copyright © 2011-2022 走看看