Chieh's Blog

Because Of Coding

ZOJ Problem Set - 3563 Alice's Sequence II

Chieh posted @ 2018年3月14日 23:46 in ZOJ , 250 阅读

飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4562

题意很清楚,构造矩阵matrix[][] 其中ai_j表示第i个数字给第j个数字提供了什么。那么就很清楚能写出矩阵,对于m个运算方案,运算k次,则需要运算k/m次全部的+k%m剩下的就是答案,所以这个题想清楚了很简单,直接矩阵快速幂m种方案的矩阵乘积为x,k%m种方案的矩阵乘积为c,初始矩阵为A,则答案矩阵为A*(x)^(k/m)*c,主要是trick!!!!搞死我了,(1)add 运算的话,可能两个值相同,那么对应的点就为2了,(2)transform 可能i和j又相同,这里的话必须执行前面的乘法再置0,如果反过来则错,其余没有什么trick点了,小心点就好了,反正我是被搞死了。//

//  main.cpp
//  zoj3563
//
//  Created by cfhaiteeh on 14/03/2018.
//  Copyright © 2018 cfhaiteeh. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define  LL long long
using namespace  std;
const int MOD=10000007;
struct Matrix{
    LL  mat[26][26];
};
int n,m,k;
Matrix MUL(Matrix a,Matrix b){
    Matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i=1;i<=n;i++){
        for(int k=1;k<=n;k++){
            if(a.mat[i][k])
            for(int j=1;j<=n;j++){
                
                c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%MOD;
            }
        }
    }
    return c;
}
Matrix poww(Matrix a,int k){
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=1;i<=n;i++)ans.mat[i][i]=1;
    while(k!=0){
        if(k%2==1){
            ans=MUL(ans,a);
        }
        a=MUL(a,a);
        k/=2;
    }
    return ans;
}
int ai[26];
int bi[11][26][26];
char ch[123];
void init(){
    for(int i=1;i<=n;i++)scanf("%d",&ai[i]);
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                if(j==k)bi[i][j][k]=1;
                else bi[i][j][k]=0;
            }
        }
        scanf("%s",ch+1);
        int u,v,w,x;
        if(ch[1]=='r'){
            scanf("%d",&u);
            bi[i][u][u]=0;
        }
        else if(ch[1]=='d'){
            scanf("%d",&u);
            bi[i][u][u]*=2;
        }
        else if(ch[1]=='a'){
            scanf("%d%d",&u,&v);
            bi[i][v][u]++;
        }
        else if(ch[1]=='s'){
            scanf("%d%d",&u,&v);
            bi[i][u][u]=0;
            bi[i][v][v]=0;
            bi[i][u][v]=1;
            bi[i][v][u]=1;
        }
        else if(ch[1]=='i'){
            scanf("%d%d",&u,&v);
            for(int j=u;j<=v;j++)bi[i][j][j]=0;
            w=u;
            for(int j=v;j>=u;j--){
                bi[i][j][w]=1;
                w++;
            }
        }
        else if(ch[1]=='t'){
            scanf("%d%d%d%d",&u,&v,&w,&x);
           
            bi[i][v][v]=u;
            bi[i][x][v]=w;
             bi[i][x][x]=0;
        }
    }
    scanf("%d",&k);
}
Matrix a,b,c;
LL ans[26];
void play(){
    
    int M=k%m;
    int F=k/m;
    memset(a.mat,0,sizeof(a.mat));
    memset(b.mat,0,sizeof(b.mat));
    
    for(int i=1;i<=n;i++){
        a.mat[i][i]=1;
    }
    
    for(int r=1;r<=m;r++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                b.mat[i][j]=bi[r][i][j];
            }}
        a=MUL(a, b);
        if(r==M){
            c=a;
        }
    }
    Matrix x=poww(a,F);
    if(M!=0){
        x=MUL(x,c);
    }
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            ans[i]=(ans[i]+x.mat[j][i]*ai[j])%MOD;
        }
    }
}
void pri(){
    
    bool fir=1;
    for(int i=1;i<=n;i++){
       
        if(!fir)printf(" ");
        fir=0;
        printf("%lld",ans[i]);
    }
    printf("\n");
}
int main() {
    // insert code here...
    while(scanf("%d",&n)!=EOF){
        init();
        play();
        pri();
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter