Submission #1307862

#TimeUsernameProblemLanguageResultExecution timeMemory
1307862exoworldgdObstacles for a Llama (IOI25_obstacles)C++20
Compilation error
0 ms0 KiB
#pragma GCC optimize("Ofast,unroll-loops,inline,fast-math,omit-frame-pointer")
#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt,tune=native,fma")
#include <bits/stdc++.h>
#define exoworldgd cin.tie(0)->sync_with_stdio(0),cout.tie(0)
using namespace std;
using ll=long long;
const int inf=1e9+1e5,LOG=20,BLOCK=1<<10;
int minr(const vector<int>&v,int a,int b){return a==b?inf:*min_element(v.begin()+a,v.begin()+b);}
struct SegTree{
    int n;
    vector<int>v,b;
    SegTree():n(-1){}
    SegTree(const vector<int>&vals){
        n=(vals.size()+BLOCK-1)/BLOCK*BLOCK,v=vals;
        while(v.size()^n)v.push_back(-inf);
        b.resize(n/BLOCK);
        for(int i=0;i<n/BLOCK;i++)b[i]=*min_element(v.begin()+i*BLOCK,v.begin()+(i+1)*BLOCK);
    }
    int query(int l,int r)const{
        int lb=l/BLOCK,rb=r/BLOCK;
        return lb==rb?minr(v,l,r):min({minr(v,l,BLOCK*(lb+1)),minr(b,lb+1,rb),minr(v,BLOCK*rb,r)});
    }
    int first_less(int i,int val)const{
        int ib=i/BLOCK,k=ib+1;
        for(int j=i;j<(ib+1)*BLOCK;j++)if(v[j]<val)return j;
        while(k<b.size()&&b[k]>=val)k++;
        for(int j=k*BLOCK;j<n;j++)if(v[j]<val)return j;
        return n;
    }
    int last_less(int i,int val)const{
        int ib=i/BLOCK,k=ib;
        for(int j=i-1;j>=ib*BLOCK;j--)if(v[j]<val)return j;
        while(k&&b[k-1]>=val)k--;
        for(int j=k*BLOCK-1;j+1;j--)if(v[j]<val)return j;
        return -1;
    }
};
tuple<int,int,int>join(tuple<int,int,int>a,tuple<int,int,int>b){return{max(get<0>(a),get<0>(b)),min(get<1>(a),get<1>(b)),get<2>(b)};}
struct Forest{
    vector<int>pos,dep;
    vector<array<tuple<int,int,int>,LOG>>rmq;
    int lca(int a,int b){
        if(dep[a]>dep[b])swap(a,b);
        for(int l=LOG-1;l+1;l--)if(dep[get<2>(rmq[b][l])]>=dep[a])b=get<2>(rmq[b][l]);
        for(int l=LOG-1;l+1;l--)if(get<2>(rmq[a][l])!=get<2>(rmq[b][l]))a=get<2>(rmq[a][l]),b=get<2>(rmq[b][l]);
        return a==b?a:(get<2>(rmq[a][0])==get<2>(rmq[b][0])?get<2>(rmq[a][0]):-1);
    }
    tuple<int,int,int>conn(int a,int b){
        auto res=make_tuple(-inf,inf,a);
        for(int l=LOG-1;l>=0;l--)if(dep[get<2>(rmq[get<2>(res)][l])]>=dep[b])res=join(res,rmq[get<2>(res)][l]);
        return res;
    }
}forest;
vector<tuple<int,int,int,int,int,int>>build(const vector<int>&t,const vector<int>&h){
    int n=t.size(),m=h.size();
    vector<int>mx={0},ord(m);
    for(int i=1;i<n;i++)if(t[i]>t[mx.back()])mx.push_back(i);
    iota(ord.begin(),ord.end(),0),sort(ord.begin(),ord.end(),[&](int i,int j){return h[i]>h[j];});
    auto hinv=h;
    for(auto&x:hinv)x*=-1;
    const auto hrmq=SegTree(h),hivrmq=SegTree(hinv),trmq=SegTree(t);
    map<int,int>act;
    vector<tuple<int,int,int,int,int,int>>lyr;
    for(auto i:mx){
        int tmp=t[i];
        vector<int>ec;
        while(!ord.empty()&&h[ord.back()]<tmp)ec.push_back(ord.back()),ord.pop_back();
        set<pair<int,int>>rng;
        for(auto c:ec)rng.insert({hivrmq.last_less(c,1-tmp)+1,hivrmq.first_less(c,1-tmp)});
        for(auto&[l,r]:rng){
            int idx=lyr.size();
            while(1){
                auto it=act.lower_bound(l);
                if(it==act.end()||it->first>=r)break;
                auto&ch=lyr[it->second];
                int mt=trmq.query(get<0>(ch),i+1);
                if(mt>hrmq.query(get<1>(ch),get<2>(ch)))get<4>(ch)=hrmq.first_less(get<1>(ch),mt),get<5>(ch)=hrmq.last_less(get<2>(ch),mt),get<3>(ch)=idx;
                act.erase(it);
            }
            act[l]=idx,lyr.push_back({i,l,r,idx,-inf,inf});
        }
    }
    return lyr;
}
void initialize(vector<int>T,vector<int>H){
    auto lyr=build(T,H);
    vector<int>pos(H.size(),-1);
    for(int i=0;i<lyr.size();i++)if(get<0>(lyr[i])==0)for(int j=get<1>(lyr[i]);j<get<2>(lyr[i]);j++)pos[j]=i;
    vector<array<tuple<int,int,int>,LOG>>rmq(lyr.size());
    vector<int>dep(lyr.size());
    for(int i=lyr.size()-1;i+1;i--){
        rmq[i][0]={get<4>(lyr[i]),get<5>(lyr[i]),get<3>(lyr[i])},dep[i]=get<3>(lyr[i])==i?0:1+dep[get<3>(lyr[i])];
        for(int l=0;l<LOG-1;l++)rmq[i][l+1]=join(rmq[i][l],rmq[get<2>(rmq[i][l])][l]);
    }
    forest.pos=pos,forest.dep=dep,forest.rmq=rmq;
}
bool can_reach(int L,int R,int S,int D){
    if(S>D)swap(S,D);
    int a=forest.pos[S],b=forest.pos[D],c=forest.lca(a,b);
    return c^-1&&get<1>(forest.conn(a,c))>=L&&get<0>(forest.conn(b,c))<=R;
}

Compilation message (stderr)

In file included from /usr/include/c++/13/string:43,
                 from /usr/include/c++/13/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:52,
                 from obstacles.cpp:3:
/usr/include/c++/13/bits/allocator.h: In destructor 'constexpr std::_Vector_base<int, std::allocator<int> >::_Vector_impl::~_Vector_impl()':
/usr/include/c++/13/bits/allocator.h:184:7: error: inlining failed in call to 'always_inline' 'constexpr std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = int]': target specific option mismatch
  184 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/13/vector:66,
                 from /usr/include/c++/13/functional:64,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:53:
/usr/include/c++/13/bits/stl_vector.h:133:14: note: called from here
  133 |       struct _Vector_impl
      |              ^~~~~~~~~~~~