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
……
可看出是线性序列,然后构造
当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); } }
相关文章推荐
- Acdream 1214 Nice Patterns Strike Back (矩阵乘法 + 状态压缩)
- zoj 2317 Nice Patterns Strike Back(矩阵乘法)
- sgu 197 Nice Patterns Strike Back 矩阵快速幂
- SGU 197.Nice Patterns Strike Back
- ZOJ 2317 Nice Patterns Strike Back
- zoj 2317 Nice Patterns Strike Back
- ZOJ2317-Nice Patterns Strike Back:矩阵快速幂,高精度
- zoj 2317 Nice Patterns Strike Back(矩阵乘法)
- 快速矩阵幂+DFS构造矩阵+大数 ACdream1214 Nice Patterns Strike Back
- ZOJ-2317 Nice Patterns Strike Back
- Nice Patterns Strike Back(位运算dp+大数矩阵快速幂)
- SGU 197 Nice Patterns Strike Back || ZOJ 2317 Nice Patterns Strike Back
- sgu197:Nice Patterns Strike Back(状压dp+矩阵乘法优化)
- 【ZOJ】Nice Patterns Strike Back(矩阵快速乘法)
- ASC1 E-Nice Patterns Strike Back
- ZOJ 2317 Nice Patterns Strike Back(矩阵快速幂)
- ASC1 E Nice Patterns Strike Back
- sgu 197 Nice Patterns Strike Back(构造矩阵快速幂)
- ZOJ2317 Nice Patterns Strike Back
- HDU5808 Price List Strike Back