题意为有n只猫 而你有m次操作 每次操作分k个步骤 每个步骤有3种选择
1:给第i个猫a个花生
2:让第i个猫把它所有的花生都吃掉
3:交换两个猫的花生
第一眼看过去以为是水题 后来发现m很大 大到o(n)都会t掉 所以就需要简化操作 用矩阵 可以将k个步骤整合成一个步骤
对于1 2 3只要构造 如下的矩阵 就可以达到相应的功能
整合成一个矩阵后 再利用矩阵快速幂来求就可以了
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include<stack>
#define inf 0x3f3f3f3f
#define ll long long
#define bug puts("bugbugbug");
using namespace std;
const int maxn = 105;
const int maxm = 105;
//ll mod=3000000007;
int a[100005];
struct Matrix {
int n, m;
ll a[maxn][maxm];
void clear() {
n = m = 0;
memset(a, 0, sizeof(a));
}
Matrix operator * (const Matrix &b) const { //实现矩阵乘法
Matrix tmp;
tmp.n = n;
tmp.m = b.m;
for (int i = 0; i < n; i++)
for (int j = 0; j < b.m; j++) tmp.a[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
if (!a[i][j]) continue;
for (int k = 0; k < b.m; k++)
tmp.a[i][k] += a[i][j] * b.a[j][k];//, tmp.a[i][k] %= mod;
}
return tmp;
}
void Copy(const Matrix &b) {
n = b.n, m = b.m;
for (int i = 0; i < n; i++)
for(int j = 0; j < m; j++) a[i][j] = b.a[i][j];
}
void unit(int sz) {
n = m = sz;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) a[i][j] = 0;
a[i][i] = 1;
}
}
};
Matrix A, B,C;
Matrix Matrix_pow(Matrix A, ll k) { //矩阵快速幂
Matrix res;
res.clear();
res.n = res.m = A.n;
for (int i = 0; i < A.n; i++) res.a[i][i] = 1;
while(k) {
if (k & 1) res.Copy(A * res);
k >>= 1;
A.Copy(A * A);
}
return res;
}
int main()
{
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k)&&n+m+k)
{
A.clear();
A.n=n+1;A.m=1;
A.a[n][0]=1;
B.clear();
B.n=B.m=n+1;
for(int i=0;i<=n;i++)
B.a[i][i]=1;
for(int i=0;i<k;i++){
char ff[20];
scanf("%s",ff);
if(ff[0]=='g'){
int a;
scanf("%d",&a);
B.a[a-1][n]++;
}
else if(ff[0]=='e'){
int a;
scanf("%d",&a);
for(int j=0;j<=n;j++)
B.a[a-1][j]=0;
}
else {
int a,b;
scanf("%d%d",&a,&b);
for(int j=0;j<=n;j++)
swap(B.a[a-1][j],B.a[b-1][j]);
}
}
C.Copy(Matrix_pow(B,m)*A);
for(int i=0;i<n;i++)
{
printf("%lld",C.a[i][0]);
if(i==n-1)printf("\n");
else printf(" ");
}
}
}
虽然m<int 但每次操作可能增加多个花生,所以注意要long long输出