• zoj Cryptography 2671 矩阵相乘 + Mod求余 + 线段树查询


    题目来源:

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1671

    代码如下:

    typedef long long LL ;
    const double EPS = 1e-12;
    const int Max_N = 30005;
    int Mod;
    struct Mat{
        int elem[3][3];
        Mat(){
            memset(elem,0, sizeof(elem));
        }
        Mat operator * ( Mat m){
            Mat s;
            for(int i=1; i<=2; i++){
                for(int j=1; j<=2; j++){
                    for( int k=1; k<=2 ; k++){
                        s.elem[i][j]= (s.elem[i][j] + elem[i][k]*m.elem[k][j]) % Mod;
                    }
                }
            }
            return s;
        }
        void read(){
            scanf("%d%d%d%d",&elem[1][1], &elem[1][2], &elem[2][1], &elem[2][2]);
        }
        void output(){
            for(int i=1; i<=2; i++)
                printf("%d %d
    ",elem[i][1] % Mod, elem[i][2] % Mod);
        }
    };
    Mat sum[Max_N <<2];
    Mat data[Max_N];
    //从下向上 更新值
    void push_up(int root){
        sum[root] = sum[root<<1] * sum[root<<1|1];
    }
    // 建树 , 从根节点出发, 根节点从1开始
    void make_tree(int L, int R, int root){
        if(L == R){
            sum[root]= data[L];
            return ;
        }
        int mid=(L + R)>>1;
        make_tree(L, mid, root<<1);
        make_tree(mid+1, R, root<<1|1);
        push_up(root);
    }
    //查询,
    Mat query(int l, int r, int L, int R, int root){
        if(l<=L && R<=r)
            return sum[root];
        int mid=(L + R)>>1;
        if(mid >= r)
            return query(l, r, L, mid, root<<1);
        else if(mid< l)
            return query(l, r, mid+1, R, root<<1|1);
        else
            return query(l,r, L, mid, root<<1) * query(l, r, mid+1, R, root<<1|1);
    }
    int main(){
        int  n, m, x, y ;
        int count =1;
        while(scanf("%d%d%d",&Mod,&n,&m)!= EOF){
            if(count > 1){
                puts("");
            }
            count++;
            for(int i=1; i<=n; i++){
                data[i].read();
            }
            make_tree(1,n,1);
            for(int i=1; i<=m; i++){
                scanf("%d%d",&x,&y);
                Mat res=query(x,y, 1,n,1);
                res.output();
                if(i!=m)
                    puts("");
            }
        }
        return 0;
    }
  • 相关阅读:
    Java注解
    java反射简单入门
    java泛型反射
    BeanUtils.populate的作用
    适配器模式
    原型模式
    抽象工厂模式
    工厂方法模式
    建造者模式
    单例模式
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3671197.html
Copyright © 2020-2023  润新知