您的位置:首页 > 其它

ACdream 1214 Nice Patterns Strike Back

2014-10-02 20:06 344 查看
线性序列 构造矩阵,

当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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: