ACdream 1214 Nice Patterns Strike Back


线性序列 构造矩阵,

当m==2时;

       0  1  2  3  //考虑位01,表示黑白

一:1  1  1  1

二:3  4  4  3

三:11 14 14 11

……

可看出是线性序列,然后构造


#include<stdio.h> 
#include<string.h> 
#include<math.h> 
#include<stdlib.h> 
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
#define ll long long
const int inf = 0x3f3f3f3f;
 
struct Bigint { 
    // representations and structures 
    string a; // to store the digits 
    int sign; // sign = -1 for negative numbers, sign = 1 otherwise 
    // constructors 
    Bigint() {} // default constructor 
    Bigint( string b ) { (*this) = b; } // constructor for string 
       
    // some helpful methods 
    int size() { // returns number of digits 
        return (int)a.size(); 
    } 
    Bigint inverseSign() { // changes the sign 
        sign *= -1; 
        return (*this); 
    } 
    Bigint normalize( int newSign ) { // removes leading 0, fixes sign 
        for( int i = (int)a.size() - 1; i > 0 && a[i] == '0'; i-- ) 
            a.erase(a.begin() + i); 
        sign = ( a.size() == 1 && a[0] == '0' ) ? 1 : newSign; 
        return (*this); 
    } 
       
    // assignment operator 
    void operator = ( string b ) { // assigns a string to Bigint 
        a = b[0] == '-' ? b.substr(1) : b; 
        reverse( a.begin(), a.end() ); 
        this->normalize( b[0] == '-' ? -1 : 1 ); 
    } 
       
    // conditional operators 
    bool operator < ( const Bigint &b ) const { // less than operator 
        if( sign != b.sign ) return sign < b.sign; 
        if( a.size() != b.a.size() ) 
            return sign == 1 ? a.size() < b.a.size() : a.size() > b.a.size(); 
        for( int i = (int)a.size() - 1; i >= 0; i-- ) if( a[i] != b.a[i] ) 
            return sign == 1 ? a[i] < b.a[i] : a[i] > b.a[i]; 
        return false; 
    } 
    bool operator == ( const Bigint &b ) const { // operator for equality 
        return a == b.a && sign == b.sign; 
    } 
    // mathematical operators 
    Bigint operator + ( Bigint b ) { // addition operator overloading 
        if( sign != b.sign ) return (*this) - b.inverseSign(); 
        Bigint c; 
        for(int i = 0, carry = 0; i<a.size() || i<b.size() || carry; i++ ) { 
            carry+=(i<a.size() ? a[i]-48 : 0)+(i<b.a.size() ? b.a[i]-48 : 0); 
            c.a += (carry % 10 + 48); 
            carry /= 10; 
        } 
        return c.normalize(sign); 
    } 
    Bigint operator - ( Bigint b ) { // subtraction operator overloading 
        if( sign != b.sign ) return (*this) + b.inverseSign(); 
        int s = sign; sign = b.sign = 1; 
        if( (*this) < b ) return ((b - (*this)).inverseSign()).normalize(-s); 
        Bigint c; 
        for( int i = 0, borrow = 0; i < a.size(); i++ ) { 
            borrow = a[i] - borrow - (i < b.size() ? b.a[i] : 48); 
            c.a += borrow >= 0 ? borrow + 48 : borrow + 58; 
            borrow = borrow >= 0 ? 0 : 1; 
        } 
        return c.normalize(s); 
    } 
    Bigint operator * ( Bigint b ) { // multiplication operator overloading 
        Bigint c("0"); 
        for( int i = 0, k = a[i] - 48; i < a.size(); i++, k = a[i] - 48 ) { 
            while(k--) c = c + b; // ith digit is k, so, we add k times 
            b.a.insert(b.a.begin(), '0'); // multiplied by 10 
        } 
        return c.normalize(sign * b.sign); 
    } 
    Bigint operator / ( Bigint b ) { // division operator overloading 
        if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 ); 
        Bigint c("0"), d; 
        for( int j = 0; j < a.size(); j++ ) d.a += "0"; 
        int dSign = sign * b.sign; b.sign = 1; 
        for( int i = (int)a.size() - 1; i >= 0; i-- ) { 
            c.a.insert( c.a.begin(), '0'); 
            c = c + a.substr( i, 1 ); 
            while( !( c < b ) ) c = c - b, d.a[i]++; 
        } 
        return d.normalize(dSign); 
    } 
    Bigint operator % ( Bigint b ) { // modulo operator overloading 
        if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 ); 
        Bigint c("0"); 
        b.sign = 1; 
        for( int i = (int)a.size() - 1; i >= 0; i-- ) { 
            c.a.insert( c.a.begin(), '0'); 
            c = c + a.substr( i, 1 ); 
            while( !( c < b ) ) c = c - b; 
        } 
        return c.normalize(sign); 
    } 
    // output method 
    void print() { 
        if( sign == -1 ) putchar('-'); 
        for( int i = (int)a.size() - 1; i >= 0; i-- ) putchar(a[i]); 
        printf("\n"); 
    } 
}; 
 
int cnt,p;
struct node
{
    int a[40][40];
}T,I;
Bigint one=string("1");
Bigint two=string("2");
Bigint zero=string("0");
Bigint n;
node multi(node A,node B)
{
    int i,j,k;
    node C;
    memset(C.a,0,sizeof(C.a));
    for(i=0;i<cnt;i++)
        for(j=0;j<cnt;j++)
        {
            for(k=0;k<cnt;k++)
            {
                C.a[i][j]+=A.a[i][k]*B.a[k][j];
                C.a[i][j]%=p;
            }
            C.a[i][j]=(C.a[i][j]+p)%p;
        }
    return C;
}
int main()
{
    string nn;
    int m;
    while(cin>>nn)
    {
        scanf("%d%d",&m,&p);
        cnt=(1<<m);
        int i,j,k,l;
        for(i=0;i<cnt;i++)
            for(j=0;j<cnt;j++)
                if(i==j)
                    I.a[i][j]=1;
                else
                    I.a[i][j]=0;
        for(i=0;i<cnt;i++)
            for(j=i;j<cnt;j++)
            {
                int flag=0;
                for(k=0;k<m-1;k++)
                {
                    int t1=((i>>k)&1);
                    int t2=((i>>(k+1))&1);
                    int t3=((j>>k)&1);
                    int t4=((j>>(k+1))&1);
                    if(t1==t2 && t1==t3 && t1==t4)
                    {
                        T.a[i][j]=T.a[j][i]=0;
                        flag=1;
                        break;
                    }
                }
                if(flag==0)
                    T.a[i][j]=T.a[j][i]=1;
            }
        n=nn;
        n=n-one;
        while(!(n==zero))
        {
            if(n%two==one)
                I=multi(I,T);
            n=n/two;
            T=multi(T,T);
        }
        int sum=0;
        for(i=0;i<cnt;i++)
            for(j=0;j<cnt;j++)
                sum=(sum+I.a[i][j])%p;
        printf("%d\n",sum);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值