zoukankan      html  css  js  c++  java
  • AGC013 E Placing Squares——模型转化+矩阵乘法

    题目:https://atcoder.jp/contests/agc013/tasks/agc013_e

    边长的平方,可以看做是在该范围内放两个不同的球的方案数。两个球可以重合。

    题意变成:给长为 n 的段放若干隔板,最前/后面有隔板,指定位置不能放隔板,相邻隔板间放两个不同球的方案数。

    dp[ 0/1/2 ] 表示从上一个隔板至今已经放了几个球。把 “能放隔板” 和 “不能放隔板” 写成两个转移矩阵,就能转移了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=1e5+5,mod=1e9+7;
    int n,m,x[N];
    struct Mtr{
      int a[3][3];
      Mtr(){memset(a,0,sizeof a);}
      Mtr operator* (const Mtr &b)const
      {
        Mtr c;
        for(int i=0;i<3;i++)
          for(int k=0;k<3;k++)
        for(int j=0;j<3;j++)
          c.a[i][j]=(c.a[i][j]+(ll)a[i][k]*b.a[k][j])%mod;
        return c;
      }
      void init()
      {
        for(int i=0;i<3;i++)for(int j=0;j<3;j++)a[i][j]=1;
        a[0][1]=a[2][1]=a[2][2]=2; a[1][0]=0;
      }
    }ans,b0,b1,tp,one;
    void pw(int n)
    {
      b0=one; tp.init();
      while(n)
        { if(n&1)b0=b0*tp; tp=tp*tp; n>>=1;}
    }
    int main()
    {
      n=rdn();m=rdn();
      for(int i=1;i<=m;i++)x[i]=rdn(); x[++m]=n;
      b1.init(); b1.a[2][1]=b1.a[2][0]=0; b1.a[2][2]=1;
      for(int i=0;i<3;i++)one.a[i][i]=1;
      ans.a[0][0]=1; pw(x[1]); ans=ans*b0;
      for(int i=1;i<m;i++)
        {
          ans=ans*b1;
          pw(x[i+1]-x[i]-1); ans=ans*b0;
        }
      printf("%d
    ",ans.a[0][2]);
      return 0;
    }
  • 相关阅读:
    Redis学习手册(Set数据类型)
    Redis学习手册(Key操作命令)
    Redis学习手册(String数据类型)
    Redis学习手册(开篇)
    SQLite学习手册(目录)
    Redis学习手册(Hashes数据类型)
    Redis学习手册(SortedSets数据类型)
    Redis学习手册(List数据类型)
    加密,解密
    异步 '省','市','区' 三级连动
  • 原文地址:https://www.cnblogs.com/Narh/p/11004648.html
Copyright © 2011-2022 走看看