Training little cats
http://poj.org/problem?id=3735
題解:、
因m的數據范圍較大,用矩陣連乘。
構建矩陣模型,peanut[N] = {0,0,。。。。0,1}:即前n個數為0,最后一個數取1
matrix[N][N],初始化條件下為單位矩陣,。。。
對貓咪進行操作轉化為在對矩陣peanut進行操作,一組操作過程轉化為矩陣matrix,那么m次操作,即對peanut*(matrix^m)
EXP:
input:
316
g?1
g?2
g?2
s?12
g?3
e?2
初始化下矩陣:peanut??
0001?即每只貓咪的花生米個數為0
初始化下matrix為單位矩陣
1000
0100
0010
0001
經過操作?
g?1
給1號1顆花生米,即在第一列的最后一行加1
1000
0100
0010
1001
g?2
1000
0100
0010
1101
g?2
1000
0100
0010
1201
s?12
//即交換第1,2列
0100
1000
0010
2101
g?3
0100
1000
0010
2111
e?2
//將第2列全部置為0
0000
1000
0010
2011
最后peanut?=?peanut*matrix*matrix.....*matrix?=?peanut*(matrix^m)故可用矩陣快速求冪
peanut的前n個數即為每只貓咪擁有的花生米數
參考文章:?矩陣乘積? ??矩陣快速冪? ?矩陣構造方法? ?
(原博客——蝸牛的足跡)?
/* *@Author: STZG *@Language: C++ */ //#include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int #define endl "\n" using namespace std; typedef long long ll; //typedef __int128 lll; const int N=100+10; const int M=100000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const double EXP = 1E-8; const int INF = 0x3f3f3f3f; int t,n,m,k,p,l,r,u,v; int ans,cnt,flag,temp,sum; ll a[N][N]; ll b[N][N]; ll s[N][N]; char str[5]; void Matrix(ll a[N][N],ll b[N][N]){ll c[N][N];memset(c,0,sizeof(c));for(int i=0;i<=n;i++){for(int k=0;k<=n;k++){if(a[i][k]){for(int j=0;j<=n;j++){c[i][j]=c[i][j]+a[i][k]*b[k][j];}}}}for(int i=0;i<=n;i++){for(int j=0;j<=n;j++){a[i][j]=c[i][j];}} } void power(int k){for(int i=0;i<=n;i++){for(int j=0;j<=n;j++){a[i][j]=0;b[i][j]=s[i][j];}}a[0][n]=1;while(k){if(k&1)Matrix(a,b);Matrix(b,b);k>>=1;}return ; } int main() { #ifdef DEBUGfreopen("input.in", "r", stdin);//freopen("output.out", "w", stdout); #endif//ios::sync_with_stdio(false);//cin.tie(0);//cout.tie(0);//scanf("%d",&t);while(~scanf("%d%d%d",&n,&m,&k)&&(n+m+k)){if(n==0&&m==0&&k==0)break;for(int i=0;i<=n;i++){for(int j=0;j<=n;j++){s[i][j]=(i==j);}}//for(int i=1;i<=k;i++){scanf("%s",str);if(str[0]=='g'){scanf("%d",&p);s[n][p-1]++;}else if(str[0]=='e'){scanf("%d",&p);for(int j=0;j<=n;j++){s[j][p-1]=0;}}else{scanf("%d%d",&l,&r);for(int j=0;j<=n;j++){swap(s[j][l-1],s[j][r-1]);}}}power(m);for(int i=1;i<=n;i++)printf("%lld%c",a[0][i-1]," \n"[i==n]);}#ifdef DEBUGprintf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC); #endif//cout << "Hello world!" << endl;return 0; }總結
以上是生活随笔為你收集整理的Training little cats的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tiling_easy version
- 下一篇: 哈尔滨工程大学ACM预热赛