vijos1049——送给圣诞夜的礼品

来源:互联网 发布:javascript 移除元素 编辑:程序博客网 时间:2024/05/16 01:59

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);}
2 0
原创粉丝点击