結果

問題 No.426 往復漸化式
ユーザー btkbtk
提出日時 2016-09-23 00:16:18
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 126 ms / 5,000 ms
コード長 5,557 bytes
コンパイル時間 1,941 ms
コンパイル使用メモリ 177,332 KB
実行使用メモリ 46,520 KB
最終ジャッジ日時 2023-08-11 03:12:54
合計ジャッジ時間 4,390 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,384 KB
testcase_01 AC 2 ms
4,380 KB
testcase_02 AC 1 ms
4,380 KB
testcase_03 AC 6 ms
4,380 KB
testcase_04 AC 5 ms
4,376 KB
testcase_05 AC 29 ms
9,532 KB
testcase_06 AC 28 ms
9,584 KB
testcase_07 AC 58 ms
46,404 KB
testcase_08 AC 57 ms
46,492 KB
testcase_09 AC 88 ms
46,340 KB
testcase_10 AC 86 ms
46,452 KB
testcase_11 AC 64 ms
46,396 KB
testcase_12 AC 102 ms
46,336 KB
testcase_13 AC 101 ms
46,444 KB
testcase_14 AC 94 ms
46,520 KB
testcase_15 AC 75 ms
46,404 KB
testcase_16 AC 122 ms
46,516 KB
testcase_17 AC 126 ms
46,400 KB
testcase_18 AC 121 ms
46,404 KB
testcase_19 AC 46 ms
46,348 KB
testcase_20 AC 64 ms
46,352 KB
testcase_21 AC 69 ms
46,352 KB
testcase_22 AC 66 ms
46,424 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>

using namespace std;


typedef long long LL;

template<typename T>void chmin(T &a,T b){a=min(a,b);}
template<typename T>void chmax(T &a,T b){a=max(a,b);}
template<typename T>
istream& operator>>(istream &is,vector<T> &v){
    for(auto &it:v)is>>it;
    return is;
}

const LL MOD = 1e9+7;
#define SIZE 400000
#define L(v) (v*2+1)
#define R(v) (v*2+2)

struct A{
    LL v[3][3];
};
struct B{
    LL v[2][2];
};
struct C{
    LL v[2][3];
};

#define mm(res,x,y,z)  for(int i=0;i<x;i++)for(int j=0;j<y;j++){res.v[i][j]=0;for(int k=0;k<z;k++)(res.v[i][j]+=l.v[i][k]*r.v[k][j])%=MOD;}
A mulmat(A l,A r){
    A res;
    mm(res,3,3,3);
    return res;
}

B mulmat(B l,B r){
    B res;
    mm(res,2,2,2);
    return res;
}
C mulmat(B l,C r){
    C res;
    mm(res,2,3,2);
    return res;
}
C mulmat(C l,A r){
    C res;
    mm(res,2,3,3);
    return res;
}
C mulmat(B b,C c,A a){
    return mulmat(mulmat(b,c),a);
}
C addmat(C l,C r){
    C res;
    for(int i=0;i<2;i++)
        for(int j=0;j<3;j++){
            res.v[i][j]=l.v[i][j]+r.v[i][j];
            if(res.v[i][j]>=MOD)res.v[i][j]-=MOD;
        }
    return res;
}
struct val{
    A a;
    B b;
    C c;
};
val getinitval(){
    val res;
    for(int i=0;i<3;i++)for(int j=0;j<3;j++)res.a.v[i][j]=0;
    for(int i=0;i<2;i++)for(int j=0;j<2;j++)res.b.v[i][j]=0;
    for(int i=0;i<2;i++)for(int j=0;j<3;j++)res.c.v[i][j]=0;
    for(int i=0;i<3;i++)res.a.v[i][i]=1;
    for(int i=0;i<2;i++)res.b.v[i][i]=1;
    return res;
}
struct node {
    int bg, ed;
    val v;
    int len() { return ed - bg + 1; };
    inline val getval() {return v;}
    inline void init(int b, int e) {
        bg = b, ed = e;
    }
    bool isleaf() { return bg == ed; }
}mem[SIZE];

inline val combine(val l, val r) {
    return val{
        mulmat(r.a,l.a),
            mulmat(l.b,r.b),
            addmat(l.c,mulmat(l.b,r.c,l.a))
            };
}

class segT {
private:
    node *t;
public:
    segT(int bg, int ed) :t(mem) { make_tree(bg, ed); }

    void update(int v) {
        node *p = t + v, *l = t + L(v), *r = t + R(v);
        if (!p->isleaf())
            p->v = combine(l->getval(), r->getval());
    }
    void set_A(int pos,A& x,int v = 0) {
        node *p = t + v, *l = t + L(v), *r = t + R(v);
        if (pos == p->bg&&pos == p->ed) {
            p->v.a=x;
            return;
        }
        if (pos <=min(pos, l->ed))
            set_A(pos, x, L(v));
        else
            set_A(pos, x, R(v));
        update(v);
    }
    void set_B(int pos,B& x,int v = 0) {
        node *p = t + v, *l = t + L(v), *r = t + R(v);
        if (pos == p->bg&&pos == p->ed) {
            p->v.b=x;
            return;
        }
        if (pos <=min(pos, l->ed))
            set_B(pos, x, L(v));
        else
            set_B(pos, x, R(v));
        update(v);
    }

    val get(int bg,int ed, int v = 0) {
        node *p = t + v, *l = t + L(v), *r = t + R(v);
        if (bg == p->bg&&ed == p->ed) {
            return p->getval();
        }
        int m;
        val res=getinitval();
        if (bg <= (m = min(ed, l->ed)))
            res=combine(res,get(bg, m, L(v)));
        if ((m = max(bg, r->bg)) <= ed)
            res=combine(res,get(m, ed, R(v)));
        return res;
    }
    void make_tree(int bg, int ed, int v = 0) {
        //cout<<bg<<" "<<ed<<endl;
        node *p = t + v;
        p->init(bg, ed);
        if (!p->isleaf()) {
            int m = (bg + ed) / 2;
            make_tree(bg, m, L(v));
            make_tree(m+1, ed, R(v));
            update(v);
        }
        else{
            p->v=getinitval();
            for(int j=0;j<2;j++)
                for(int k=0;k<3;k++)
                    p->v.c.v[j][k]=6*bg+j*3+k;

        }
    }
};

struct cww{cww(){
    ios::sync_with_stdio(false);cin.tie(0);
        
}}init;
LL a0[3];
LL bn[2];
LL ai[3];
LL bi[2];
int main(){
    int n;
    cin>>n;
    for(int i=0;i<3;i++)cin>>a0[i];
    for(int i=0;i<2;i++)cin>>bn[i];

    segT tree(0,n);
    int q;
    cin>>q;
    while(q--){
        string s;int i;
        cin>>s>>i;
        if(s=="a"){
            A v;
            for(int i=0;i<3;i++)for(int j=0;j<3;j++)cin>>v.v[i][j];
            tree.set_A(i,v);
        }
        else if(s=="b"){
            B v;
            for(int i=0;i<2;i++)for(int j=0;j<2;j++)cin>>v.v[i][j];
            tree.set_B(i,v);
        }
        else if(s=="ga"){
            if(i==0){
                cout<<a0[0]<<" "<<a0[1]<<" "<<a0[2]<<endl;
            }
            else{
                val v= tree.get(0,i-1);
                for(int i=0;i<3;i++){
                    ai[i]=0;
                    for(int j=0;j<3;j++)
                        (ai[i]+=v.a.v[i][j]*a0[j])%=MOD;
                }
                cout<<ai[0]<<" "<<ai[1]<<" "<<ai[2]<<endl;
            }
        }
        else if(s=="gb"){
            if(i==n){
                cout<<bn[0]<<" "<<bn[1]<<endl;
            }else{
                val v= tree.get(0,i);
                for(int i=0;i<3;i++){
                    ai[i]=0;
                    for(int j=0;j<3;j++)
                        (ai[i]+=v.a.v[i][j]*a0[j])%=MOD;
                }
                v=tree.get(i+1,n);
                for(int i=0;i<2;i++){
                    bi[i]=0;
                    for(int j=0;j<2;j++)
                        (bi[i]+=v.b.v[i][j]*bn[j])%=MOD;
                    for(int j=0;j<3;j++)
                        (bi[i]+=v.c.v[i][j]*ai[j])%=MOD; 
                }
                cout<<bi[0]<<" "<<bi[1]<<endl;             
            }
        }
    }
    return 0;
}
0