Submission #1254869

#TimeUsernameProblemLanguageResultExecution timeMemory
1254869PenguinsAreCuteObstacles for a Llama (IOI25_obstacles)C++20
100 / 100
327 ms25584 KiB
#include "obstacles.h"
#include <bits/stdc++.h>
using namespace std;
mt19937_64 rng(69);
struct seg {
        int n;
        vector<int> v;
        seg(int _n): n(_n), v(2*_n,-1e9-5) {}
        void up(int x, int u) {
                for(x+=n;x;x>>=1)
                        v[x]=max(v[x],u);
        }
        int qry(int l, int r) {
                int ans = -1e9-5;
                for(l+=n,r+=n+1;l<r;l>>=1,r>>=1) {
                        if(l&1)
                                ans=max(ans,v[l++]);
                        if(r&1)
                                ans=max(ans,v[--r]);
                }
                return ans;
        }
};
seg lft(0), rgt(0);
vector<unsigned long long> cc;
void initialize(std::vector<int> T, std::vector<int> H) {
        int N = T.size(), M = H.size();
        /*
        for(int i=0;i<N;i++) {
                for(int j=0;j<M;j++)
                        cerr<<(T[i]>H[j]?'.':'#');
                cerr<<"\n";
        }
        */
        lft = seg(M);
        rgt = seg(M);
        seg minH(M);
        for(int i=0;i<M;i++)
                minH.up(i,-H[i]);
        cc.resize(M,0);
        cc[0] = 0;
        vector<int> maxT(N+1), minT(N+1);
        maxT[0] = 0;
        minT[0] = 1e9 + 7;
        for(int i=0;i<N;i++) {
                maxT[i+1] = max(maxT[i],T[i]);
                minT[i+1] = min(minT[i],T[i]);
        }
        // L shape covering left
        vector<int> mono;
        for(int i=0;i<M;i++) {
                while(mono.size() && H[mono.back()] >= H[i])
                        mono.pop_back();
                mono.push_back(i);
                int pos = upper_bound(maxT.begin(),maxT.end(),H[i]) - maxT.begin() - 1;
                if(!pos)
                        continue;
                if(pos == N)
                        lft.up(i,1);
                int curTemp = minT[pos];
                auto it = partition_point(mono.begin(),mono.end(),[&H,curTemp](int x) {
                        return H[x] < curTemp;
                });
                int L = (it==mono.begin()?-1:*--it);
                lft.up(i,-L);
        }
        // L shape covering right
        mono.clear();
        for(int i=M;i--;) {
                while(mono.size() && H[mono.back()] >= H[i])
                        mono.pop_back();
                mono.push_back(i);
                int pos = upper_bound(maxT.begin(),maxT.end(),H[i]) - maxT.begin() - 1;
                if(!pos)
                        continue;
                if(pos == N)
                        rgt.up(i,N);
                int curTemp = minT[pos];
                auto it = partition_point(mono.begin(),mono.end(),[&H,curTemp](int x) {
                        return H[x] < curTemp;
                });
                int R = (it==mono.begin()?M:*--it);
                rgt.up(i,R);
        }
        // boxed in
        vector<pair<int,int>> sortH(M);
        for(int i=0;i<M;i++)
                sortH[i] = {H[i], i};
        sort(sortH.begin(),sortH.end(),greater<pair<int,int>>());
        set<int> seen;
        for(auto [h, i]: sortH) {
                auto it = seen.insert(i).first;
                int pos = upper_bound(maxT.begin(),maxT.end(),H[i]) - maxT.begin() - 1;
                if(!pos)
                        continue;
                int curTemp = minT[pos];
                if(it != seen.begin() && curTemp <= -minH.qry(*prev(it),*it)) {
                        unsigned long long cur = rng();
                        cc[*prev(it)] += cur;
                        cc[*it] -= cur;
                }
                if(next(it) != seen.end() && curTemp <= -minH.qry(*it,*next(it))) {
                        unsigned long long cur = rng();
                        cc[*next(it)] += cur;
                        cc[*it] -= cur;
                }
        }
        for(int i=1;i<M;i++)
                cc[i] += cc[i-1];
}

bool can_reach(int L, int R, int S, int D) {
        if(S > D)
                swap(S, D);
        return L <= -lft.qry(S,D) && R >= rgt.qry(S,D) && cc[S] == cc[D];
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...