Cellular Automaton UVA - 1386

Cellular Automaton UVA - 1386
无数次次RE原因竟然是,开了一个int的n输入用ll型的,简直分分钟奔溃。
思路:开n*n的矩阵内存会爆,这里通过找系数矩阵的规律,用一行代表n行的数。
例如样例1的第一行系数矩阵:1 1 0 0 1,第二行时右移一位1 1 1 0 0 后面即使变换后也是这个道理。

#include<iostream>
#include<cstdio> 
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
struct  matrix{
    ll x[551];
};
ll n,m;
matrix multi(matrix a,matrix b){
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    int t=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
                if(t==n) t=0;
                temp.x[i]+=a.x[j]*b.x[t++];
            }
            t--;temp.x[i]%=m;
    }
    return temp;
}
matrix quick_multi(matrix a,ll k)//矩阵快速幂
{
    if(k==1) return a;
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    temp.x[0]=1;
    if(k==0) return temp;
    while(k){
        if(k&1)
            temp=multi(temp,a);
        a=multi(a,a);
        k>>=1;
    }
    return temp;
}

int main()
{
    int d,k;
    ll b[550];matrix a;
    while(scanf("%lld%lld%lld%lld",&n,&m,&d,&k)!=EOF)
    {
        memset(a.x,0,sizeof(a.x));
        memset(b,0,sizeof(b));
        for(int i=0;i<n;i++) scanf("%lld",&b[i]);
        a.x[0]=1;
        for(int i=1;i<=d;i++)
        {
            a.x[i]=1;
            int p=-i;if(p<0) p+=n;
            a.x[p]=1;
        }
        a=quick_multi(a,k);
        //for(int i=0;i<n;i++) cout<<a.x[i]<<" ";
            //cout<<endl;
        int t=0;
        for(int i=0;i<n;i++){
            ll ans=0;
        for(int j=0;j<n;j++){
                if(t==n) t=0;
                ans+=b[j]*a.x[t++];
            }
            t--;ans%=m;//少取余??
            i==0?printf("%lld",ans):printf(" %lld",ans);
         }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Miranda_ymz/article/details/81605750
今日推荐