結果

問題 No.2697 Range LIS Query
ユーザー GOTKAKOGOTKAKO
提出日時 2024-03-22 23:11:25
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 618 ms / 10,000 ms
コード長 3,461 bytes
コンパイル時間 2,805 ms
コンパイル使用メモリ 212,976 KB
実行使用メモリ 41,048 KB
最終ジャッジ日時 2024-03-22 23:11:36
合計ジャッジ時間 10,153 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,676 KB
testcase_01 AC 2 ms
6,676 KB
testcase_02 AC 2 ms
6,676 KB
testcase_03 AC 13 ms
6,676 KB
testcase_04 AC 13 ms
6,676 KB
testcase_05 AC 13 ms
6,676 KB
testcase_06 AC 502 ms
41,048 KB
testcase_07 AC 536 ms
41,048 KB
testcase_08 AC 501 ms
41,048 KB
testcase_09 AC 473 ms
41,048 KB
testcase_10 AC 446 ms
41,048 KB
testcase_11 AC 443 ms
41,048 KB
testcase_12 AC 325 ms
39,712 KB
testcase_13 AC 366 ms
37,752 KB
testcase_14 AC 496 ms
37,936 KB
testcase_15 AC 618 ms
41,048 KB
testcase_16 AC 606 ms
41,048 KB
testcase_17 AC 588 ms
41,048 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

struct SS{int v[5][5],len;};
using FF = int;
class LazySegmentTree{
    public:
    int siz = 1;
    vector<SS> dat;
    vector<FF> lazy;
 
    FF ID = 0;
    SS op(SS a,SS b){
        if(a.len == 0) return b;
        if(b.len == 0) return a;
        SS ret; ret.len = a.len+b.len;
        for(int i=1; i<5; i++) for(int k=i; k<5; k++) ret.v[i][k] = 0;
        for(int i=1; i<5; i++) for(int k=i; k<5; k++) for(int l=k; l<5; l++) for(int m=l; m<5; m++){
            ret.v[i][m] = max(ret.v[i][m],a.v[i][k]+b.v[l][m]);
        }
        return ret;
    }
    SS mapping(FF f, SS x){
        if(f == 0) return x;
        SS ret; ret.len = x.len;
        for(int i=1; i<5; i++) for(int k=i; k<5; k++) ret.v[i][k] = 0;
        ret.v[f][f] = x.len; return ret;
    }
    FF composition(FF f, FF g){
        if(f == ID) return g;
        if(g == ID) return f;
        return f;
    }
    SS e(){SS ret; ret.len = 0; return ret;}
    FF id(){return ID;}
 
    //op区間演算 mapping lazy→data composition lazy→lazy
    //e 単位元 id map(id,a)=a
 
    void make(int N){
        while(siz < N) siz *= 2;
        dat.resize(siz*2,e());
        lazy.resize(siz*2,ID);
    }
 
    void make2(int N,vector<SS> &A){
        make(N);
        for(int i=0; i<N; i++){
            int pos = i+siz-1;
            dat.at(pos) = A.at(i);
        }
        for(int i=siz-2; i>=0; i--) dat.at(i) = op(dat.at(i*2+1),dat.at(i*2+2));
    }
    
    void eval(int u,int a,int b){
        if(lazy.at(u) != id()){
            dat.at(u) = mapping(lazy.at(u),dat.at(u));
            if(b-a > 1){
                lazy.at(u*2+1) = composition(lazy.at(u),lazy.at(u*2+1));
                lazy.at(u*2+2) = composition(lazy.at(u),lazy.at(u*2+2));
            }
            lazy.at(u) = id();
        }
    }
 
    void findadd(int L,int R,int a,int b,int u,FF x){
        eval(u,a,b);
        if(R <= a || b <= L) return;
        if(L <= a && b <= R){
            lazy.at(u) = composition(x,lazy.at(u));
            eval(u,a,b);
        }
        else{
            findadd(L,R,a,(a+b)/2,u*2+1,x);
            findadd(L,R,(a+b)/2,b,u*2+2,x);
            dat.at(u) = op(dat.at(u*2+1),dat.at(u*2+2));
        }
    }
    void update(int L,int R,FF x){findadd(L,R,0,siz,0,x);}
 
    SS findans(int L,int R,int a,int b,int u){
        if(R <= a || b <= L) return e();
        eval(u,a,b);
        if(L <= a && b <= R) return dat.at(u);
 
        return op(findans(L,R,a,(a+b)/2,u*2+1),findans(L,R,(a+b)/2,b,u*2+2));
    }
 
    SS get(int pos){return findans(pos,pos+1,0,siz,0);}
    SS rangeans(int l,int r){return findans(l,r,0,siz,0);}
    SS allrange(){return findans(0,siz,0,siz,0);}
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int N; cin >> N;
    vector<SS> A(N);
    for(int i=0; i<N; i++){
        int a; cin >> a;
        SS now; now.len = 1;
        for(int i=1; i<5; i++) for(int k=i; k<5; k++) now.v[i][k] = 0;
        now.v[a][a] = 1; A.at(i) = now;
    }
    LazySegmentTree Z; Z.make2(N,A);

    int Q; cin >> Q;
    while(Q--){
        int t,l,r; cin >> t >> l >> r; l--;
        if(t == 1){
            SS now = Z.rangeans(l,r);
            int answer = 0;
            for(int i=1; i<5; i++) for(int k=i; k<5; k++) answer = max(answer,now.v[i][k]);
            cout << answer << endl;
        }
        if(t == 2){
            int x; cin >> x;
            Z.update(l,r,x);
        }
    }
}
0