vijos1049
这题。。我已经不想说什么了
(╯—﹏—)╯(┷━━━┷
这题根据题目意思,暴力做法应该是模拟,模拟k次
然而100%数据k=maxlongint-1;
模拟显然炸飞
好吧我一开始真的不知道这题要怎么搞到log或者sqrt
看了下题解
矩阵快速幂=_=
突然无言以对
其实思路很简单
例如n=4
我们构造一个初始矩阵
{1}
{2}
{3}
{4}
{..}
然后比如我们要一次变化:3214
那么我们再构造一个只有0,1的n*n的矩阵
{0,0,1,0}
{0,1,0,0}
{1,0,0,0}
{0,0,0,1}
就是v[i][s[i]]=1
至于为什么这样呢?
模拟一下就可以理解了
毕竟我这么傻的人都想到了
我们把m次变化看作一整个变化c(a)
这是很容易理解的,如果不能理解。。拿两个变化的矩阵乘一下就知道了
因为k远大于m
所以我们可以使用快速幂来很快的求出c(a)^k/m
余下小于m次的变化我们再去for循环乘一遍就好了
这里注意一下!
本题快速幂一定要非递归!!
递归快速幂re…
【请吸取前人血的教训 正确率已一蹶不振
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#define inf 1e9
#define ll long long
#define For(i,j,k) for(int i=j;i<=k;i++)
#define Dow(i,j,k) for(int i=k;i>=j;i--)
using namespace std;
int n,m,k,tt;
struct mat
{
int v[101][101];
int size_x,size_y;
mat(){memset(v,0,sizeof v);size_x=size_y=0;}
}tmp[201];
inline mat mul(mat x,mat y)
{
mat rul;
rul.size_y=y.size_y;rul.size_x=x.size_x;
For(i,1,x.size_x)
For(j,1,y.size_y)
{
int tmp=0;
For(k,1,x.size_y)
tmp=tmp+x.v[i][k]*y.v[k][j];
rul.v[i][j]=tmp;
}
return rul;
}
inline void out(mat x)
{
For(i,1,x.size_x)
{
For(j,1,x.size_y)
cout<<x.v[i][j]<<' ';
}
cout<<endl;
}
inline mat ksm(mat x,int y)
{
mat sum=x;y--;for(;y;y>>=1){if(y&1)sum=mul(sum,x);x=mul(x,x);}return sum;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
mat t;
For(i,1,n)
{
scanf("%d",&tt);
t.v[i][tt]=1;
}
mat b;
For(i,1,n)
b.v[i][1]=i;
b.size_x=n;b.size_y=1;
t.size_x=t.size_y=n;
tmp[1]=t;
For(i,2,m)
{
For(j,1,n)
{
scanf("%d",&tt);
tmp[i].v[j][tt]=1;
}
tmp[i].size_x=tmp[i].size_y=n;
t=mul(tmp[i],t);
}
if(k>=m)
b=mul(ksm(t,k/m),b);
For(i,1,k%m)
b=mul(tmp[i],b);
out(b);
}