結果

問題 No.3671 Reusable Lazy Segment Tree
コンテスト
ユーザー あいすあうと
提出日時 2026-09-05 01:21:44
言語 C++23
(gcc 15.3.0 + boost 1.92.0 + ACL)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
TLE  
実行時間 -
コード長 10,096 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 5,067 ms
コンパイル使用メモリ 395,708 KB
実行使用メモリ 44,176 KB
最終ジャッジ日時 2026-09-05 01:22:05
合計ジャッジ時間 19,992 ms
ジャッジサーバーID
(参考情報)
judge3_0 / judge4_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 10 TLE * 1 -- * 8
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
using i128=__int128;
using P=pair<ll,ll>;
template<typename T> using vc=vector<T>;
template<typename T> using vv=vc<vc<T>>;
using vl=vc<ll>;
using vvl=vc<vc<ll>>;
using vul=vc<ull>;
using vs=vc<string>;
using vb=vc<bool>;
#define rep(i,s,n) for(ll i=s;i<(n);i++)
#define Rep(i,s,n) for(ll i=n;i>=s;i--)
#define nall(x) x.begin(),x.end()
#define rall(a) a.rbegin(),a.rend()
#define pb push_back
#define eb emplace_back
#define pob pop_back
#define nexp(v) next_permutation(v)
#define prep(v) prev_permutation(v)
#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
#define M1 cout<<"-1"<<endl
const long long INF=(1LL<<62)-(1LL<<31)-1;
#define endl '\n'
using mint=modint998244353;
using mint7=modint1000000007;
//vl dx={1,-1,0,0};vl dy={0,0,1,-1};
//vl dx={0,0,1,1,1,-1,-1,-1};vl dy={1,-1,0,1,-1,0,1,-1};
bool out_grid(ll i, ll j, ll h, ll w){return (!(0<=i && i<h && 0<=j && j<w));}
void chmin(ll &a,ll b){if(a>b)a=b;}
void chmax(ll &a,ll b){if(a<b)a=b;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll ceil_div(ll a,ll b){return (a+(b-1))/b;}

template<typename Node>
struct PersistentRBSTBase{
    using Ptr=Node*;

    static constexpr size_t BLOCK=1<<14;
    vc<unique_ptr<Node[]>> pool;
    size_t used=0;

    template<typename...Args>
    Ptr my_new(Args&&...args){
        size_t b=used/BLOCK,o=used%BLOCK;
        if(b==pool.size())pool.eb(make_unique<Node[]>(BLOCK));
        Ptr p=&pool[b][o];
        *p=Node(forward<Args>(args)...);
        ++used;
        return p;
    }

    size_t checkpoint()const{return used;}
    void rollback(size_t p){
        assert(p<=used);
        used=p;
    }

    Ptr make_tree()const{return nullptr;}
    int size(Ptr t)const{return count(t);}

    Ptr merge(Ptr l,Ptr r){
        if(!l||!r)return l?l:r;
        if((uint64_t)rng()*(l->cnt+r->cnt)>>32<(uint32_t)l->cnt){
            Ptr t=clone(l);
            push(t);
            t->r=merge(t->r,r);
            return update(t);
        }else{
            Ptr t=clone(r);
            push(t);
            t->l=merge(l,t->l);
            return update(t);
        }
    }

    pair<Ptr,Ptr> split(Ptr t,int k){
        assert(0<=k&&k<=count(t));
        if(!t)return {nullptr,nullptr};
        Ptr u=clone(t);
        push(u);
        if(k<=count(u->l)){
            auto [a,b]=split(u->l,k);
            u->l=b;
            return {a,update(u)};
        }else{
            auto [a,b]=split(u->r,k-count(u->l)-1);
            u->r=a;
            return {update(u),b};
        }
    }

    Ptr build(int l,int r,const vc<decltype(Node::key)>&v){
        if(l==r)return nullptr;
        int m=(l+r)>>1;
        Ptr t=my_new(v[m]);
        t->l=build(l,m,v);
        t->r=build(m+1,r,v);
        return update(t);
    }

    Ptr build(const vc<decltype(Node::key)>&v){
        return build(0,(int)v.size(),v);
    }

    template<typename...Args>
    Ptr insert(Ptr t,int k,Args&&...args){
        assert(0<=k&&k<=count(t));
        auto [a,b]=split(t,k);
        return merge(merge(a,my_new(forward<Args>(args)...)),b);
    }

    Ptr erase(Ptr t,int k){
        assert(0<=k&&k<count(t));
        auto [a,b]=split(t,k);
        auto [c,d]=split(b,1);
        return merge(a,d);
    }

protected:
    static uint32_t rng(){
        static uint64_t x=88172645463325252ULL;
        x^=x<<7;
        x^=x>>9;
        return (uint32_t)x;
    }

    int count(Ptr t)const{return t?t->cnt:0;}
    Ptr clone(Ptr t){return t?my_new(*t):nullptr;}
    virtual void push(Ptr)=0;
    virtual Ptr update(Ptr)=0;
};

template<typename S,typename F>
struct PersistentLazyReversibleRBSTNode{
    using Self=PersistentLazyReversibleRBSTNode<S,F>;
    Self*l=nullptr,*r=nullptr;
    S key,sum;
    F lazy;
    int cnt=1;
    bool rev=false;

    PersistentLazyReversibleRBSTNode(const S&x=S(),const F&f=F()):key(x),sum(x),lazy(f){}
};

template<
    typename S,
    typename F,
    S(*op)(S,S),
    S(*mapping)(S,F),
    F(*composition)(F,F),
    S(*ts)(S)
>
struct PersistentLazyReversibleRBST:PersistentRBSTBase<PersistentLazyReversibleRBSTNode<S,F>>{
    using Node=PersistentLazyReversibleRBSTNode<S,F>;
    using Base=PersistentRBSTBase<Node>;
    using Ptr=typename Base::Ptr;

    using Base::build;
    using Base::clone;
    using Base::count;
    using Base::erase;
    using Base::insert;
    using Base::merge;
    using Base::size;
    using Base::split;

    S fold(Ptr t,int l,int r)const{
        assert(0<=l&&l<=r&&r<=count(t));
        return fold_impl(t,l,r,F(),false);
    }

    S get(Ptr t,int k)const{
        assert(0<=k&&k<count(t));
        return fold(t,k,k+1);
    }

    S all_fold(Ptr t)const{
        return t?t->sum:S();
    }

    Ptr reverse(Ptr t,int l,int r){
        assert(0<=l&&l<=r&&r<=count(t));
        if(l==r)return t;
        auto [a,b]=split(t,l);
        auto [c,d]=split(b,r-l);
        toggle(c);
        return merge(a,merge(c,d));
    }

    Ptr apply(Ptr t,int l,int r,const F&f){
        assert(0<=l&&l<=r&&r<=count(t));
        if(l==r)return t;
        auto [a,b]=split(t,l);
        auto [c,d]=split(b,r-l);
        propagate(c,f);
        return merge(a,merge(c,d));
    }

    Ptr set(Ptr t,int k,const S&x){
        assert(0<=k&&k<count(t));
        auto [a,b]=split(t,k);
        auto [c,d]=split(b,1);
        return merge(a,merge(this->my_new(x),d));
    }

protected:
    S sum(Ptr t)const{return t?t->sum:S();}

    void toggle(Ptr t){
        if(!t)return;
        swap(t->l,t->r);
        t->sum=ts(t->sum);
        t->rev^=1;
    }

    void propagate(Ptr t,const F&f){
        if(!t)return;
        t->lazy=composition(t->lazy,f);
        t->key=mapping(t->key,f);
        t->sum=mapping(t->sum,f);
    }

    void push(Ptr t)override{
        if(!t||(!t->rev&&t->lazy==F()))return;
        if(t->l)t->l=clone(t->l);
        if(t->r)t->r=clone(t->r);
        if(t->rev){
            toggle(t->l);
            toggle(t->r);
            t->rev=false;
        }
        if(t->lazy!=F()){
            propagate(t->l,t->lazy);
            propagate(t->r,t->lazy);
            t->lazy=F();
        }
    }

    Ptr update(Ptr t)override{
        push(t);
        t->cnt=1;
        t->sum=t->key;
        if(t->l){
            t->cnt+=t->l->cnt;
            t->sum=op(t->l->sum,t->sum);
        }
        if(t->r){
            t->cnt+=t->r->cnt;
            t->sum=op(t->sum,t->r->sum);
        }
        return t;
    }

    S fold_impl(Ptr t,int l,int r,const F&anc_lazy,bool anc_rev)const{
        if(!t||l==r)return S();
        int n=count(t);
        if(l==0&&r==n){
            S res=anc_rev?ts(t->sum):t->sum;
            return mapping(res,anc_lazy);
        }

        Ptr left=anc_rev?t->r:t->l;
        Ptr right=anc_rev?t->l:t->r;
        int ls=count(left);
        F child_lazy=composition(t->lazy,anc_lazy);
        bool child_rev=t->rev^anc_rev;

        S res=S();
        bool has=false;

        auto add=[&](const S&x){
            if(has)res=op(res,x);
            else res=x,has=true;
        };

        if(l<ls)add(fold_impl(left,l,min(r,ls),child_lazy,child_rev));
        if(l<=ls&&ls<r)add(mapping(t->key,anc_lazy));
        if(ls+1<r)add(fold_impl(right,max(0,l-ls-1),r-ls-1,child_lazy,child_rev));

        return has?res:S();
    }
};

constexpr uint32_t mask=(1u<<30)-1;

struct F{
    uint32_t keep,set;

    F(uint32_t keep_=mask,uint32_t set_=0):keep(keep_),set(set_){}

    friend bool operator==(const F&a,const F&b){
        return a.keep==b.keep&&a.set==b.set;
    }

    friend bool operator!=(const F&a,const F&b){
        return !(a==b);
    }
};

struct S{
    array<uint32_t,17> cnt{};
    uint32_t sum=0;
    int len=0;

    S()=default;

    S(uint32_t x,int len_):sum(x&mask),len(len_){
        if(len==1)cnt[0]=x&mask;
    }
};

S op(S a,S b){
    S res;
    res.len=a.len+b.len;
    res.sum=(a.sum+b.sum)&mask;

    uint32_t carry=0;

    rep(k,0,17){
        uint32_t x=a.cnt[k];
        uint32_t y=b.cnt[k];
        uint32_t z=x^y;

        res.cnt[k]=z^carry;
        carry=(x&y)|(carry&z);
    }

    return res;
}

S mapping(S x,F f){
    if(x.len==0)return x;

    uint32_t affected=mask^f.keep;
    uint64_t old=0;

    rep(k,0,17){
        old+=(uint64_t)(x.cnt[k]&affected)<<k;

        x.cnt[k]=
            (x.cnt[k]&f.keep)|
            (((x.len>>k)&1)?f.set:0);
    }

    uint64_t nw=(uint64_t)x.len*f.set;

    x.sum=(uint32_t)(
        (uint64_t)x.sum+nw-old
    )&mask;

    return x;
}

F composition(F f,F g){
    return {
        f.keep&g.keep,
        (f.set&g.keep)|g.set
    };
}
S ts(S x){return x;}

using RBST=PersistentLazyReversibleRBST<S,F,op,mapping,composition,ts>;
RBST rbst;
RBST::Ptr root=nullptr;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int n,m,Q,q;
    cin >> n >> m;
    vc<uint32_t> a(n);
    rep(i,0,n)cin >> a[i];
    vc<int> l(m),r(m),L(m),R(m);
    vc<uint32_t> x(m);
    rep(i,0,m)cin >> l[i];
    rep(i,0,m)cin >> r[i];
    rep(i,0,m)cin >> x[i];
    rep(i,0,m)cin >> L[i];
    rep(i,0,m)cin >> R[i];
    vc<S> init;
    rep(i,0,n)init.eb(a[i],1);
    root=rbst.build(init);
    auto base=root;
    uint32_t cp=rbst.checkpoint();
    auto clp=[&](uint32_t p,uint32_t y)->int{
        uint32_t v=p^y;
        if(v<1)return 1;
        else if(v>(uint32_t)n)return n;
        else return (int)v;
    };
    cin >> Q;
    rep(i,1,Q+1){
        int s;
        cin >> s >> q;
        root=base;
        uint32_t y=i;
        rep(j,1,q+1){
            int z=(s+j)%m;
            int u=clp(l[z],y),v=clp(r[z],y),U=clp(L[z],y),V=clp(R[z],y);
            int lp=min(u,v),rp=max(u,v),Lp=min(U,V),Rp=max(U,V);
            uint32_t c=(x[z]^y)&mask;
            if((z+1)%2==0)root=rbst.apply(root,lp-1,rp,F(mask^c,c));
            else root=rbst.apply(root,lp-1,rp,F(c,0));
            y=rbst.fold(root,Lp-1,Rp).sum;
        }
        cout << y << endl;
        rbst.rollback(cp);
    }
}
0