Skip to content

Commit d7df478

Browse files
Add Segment Tree that takes the merge method as a template argument.
1 parent 3d8ffd0 commit d7df478

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// Source: https://codeforces.com/contest/1436/submission/96572644
2+
// Was looking for a Segtree template to which I can pass something like `[&](int x, int y) {return min(x, y);}`
3+
// to create a segment tree.
4+
// Also, build, query and update are all iterative.
5+
// Credits to tute7627 (https://codeforces.com/profile/tute7627).
6+
7+
//#define _GLIBCXX_DEBUG
8+
9+
#include<bits/stdc++.h>
10+
using namespace std;
11+
12+
#define endl '\n'
13+
#define lfs cout<<fixed<<setprecision(10)
14+
#define ALL(a) (a).begin(),(a).end()
15+
#define ALLR(a) (a).rbegin(),(a).rend()
16+
#define spa << " " <<
17+
#define fi first
18+
#define se second
19+
#define MP make_pair
20+
#define MT make_tuple
21+
#define PB push_back
22+
#define EB emplace_back
23+
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
24+
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
25+
using ll = long long;
26+
using ld = long double;
27+
const ll MOD1 = 1e9+7;
28+
const ll MOD9 = 998244353;
29+
const ll INF = 1e18;
30+
using P = pair<ll, ll>;
31+
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
32+
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
33+
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
34+
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
35+
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
36+
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
37+
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}
38+
template<typename T>void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};
39+
void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++){for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};
40+
template<typename T>void debug(vector<T>&v,ll n){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};
41+
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
42+
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
43+
vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
44+
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
45+
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
46+
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << p.first << " " << p.second;}
47+
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;}
48+
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
49+
int popcount(ll x){return __builtin_popcountll(x);};
50+
int poplow(ll x){return __builtin_ctzll(x);};
51+
int pophigh(ll x){return 63 - __builtin_clzll(x);};
52+
template< typename Monoid ,typename F>
53+
struct SegmentTree {
54+
int sz, n;
55+
vector< Monoid > seg;
56+
const F f;
57+
const Monoid M1;
58+
59+
SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1), n(n){
60+
sz = 1;
61+
while(sz < n) sz <<= 1;
62+
seg.assign(2 * sz, M1);
63+
}
64+
65+
void set(int k, const Monoid &x) {
66+
seg[k + sz] = x;
67+
}
68+
69+
void build() {
70+
for(int k = sz - 1; k > 0; k--) {
71+
seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
72+
}
73+
}
74+
75+
void update(int k, const Monoid &x) {
76+
k += sz;
77+
seg[k] = x;
78+
while(k >>= 1) {
79+
seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
80+
}
81+
}
82+
83+
Monoid query(int a, int b) {
84+
if(a>=b)return M1;
85+
Monoid L = M1, R = M1;
86+
for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
87+
if(a & 1) L = f(L, seg[a++]);
88+
if(b & 1) R = f(seg[--b], R);
89+
}
90+
return f(L, R);
91+
}
92+
93+
Monoid operator[](const int &k) const {
94+
return seg[k + sz];
95+
}
96+
97+
template< typename C >
98+
int find_subtree(int a, const C &check, Monoid &M, bool type) {
99+
while(a < sz) {
100+
Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
101+
if(check(nxt)) a = 2 * a + type;
102+
else M = nxt, a = 2 * a + 1 - type;
103+
}
104+
return a - sz;
105+
}
106+
//[a,x]が条件を満たす最初のx,満たさなければ-1
107+
template< typename C >
108+
int find_first(int a, const C &check) {
109+
Monoid L = M1;
110+
if(a <= 0) {
111+
if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);
112+
return -1;
113+
}
114+
int b = sz;
115+
for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
116+
if(a & 1) {
117+
Monoid nxt = f(L, seg[a]);
118+
if(check(nxt)) return find_subtree(a, check, L, false);
119+
L = nxt;
120+
++a;
121+
}
122+
}
123+
return -1;
124+
}
125+
126+
template< typename C >
127+
int find_last(int b, const C &check) {
128+
Monoid R = M1;
129+
if(b >= sz) {
130+
if(check(f(seg[1], R))) return find_subtree(1, check, R, true);
131+
return -1;
132+
}
133+
int a = sz;
134+
for(b += sz; a < b; a >>= 1, b >>= 1) {
135+
if(b & 1) {
136+
Monoid nxt = f(seg[--b], R);
137+
if(check(nxt)) return find_subtree(b, check, R, true);
138+
R = nxt;
139+
}
140+
}
141+
return -1;
142+
}
143+
void print(){
144+
for(ll i=0;i<n;i++)if((*this)[i]==M1)cout<<"x ";else cout<<(*this)[i]<<" ";
145+
cout<<endl;
146+
}
147+
};
148+
int main(){
149+
cin.tie(nullptr);
150+
ios_base::sync_with_stdio(false);
151+
ll res=0,buf=0;
152+
bool judge = true;
153+
ll n;cin>>n;
154+
vector<ll>a(n);
155+
rep(i,0,n)cin>>a[i],a[i]--;
156+
auto ff=[&](ll x,ll y){return min(x,y);};
157+
SegmentTree<ll,decltype(ff)>seg(n+1,ff,LLONG_MAX);
158+
vector<bool>t(n+2);
159+
rep(i,0,n+1)seg.set(i,-1);
160+
seg.build();
161+
rep(i,0,n){
162+
ll mi=seg.query(0,a[i]);
163+
if(mi>seg[a[i]])t[a[i]]=true;
164+
seg.update(a[i],i);
165+
}
166+
rep(i,0,n+1){
167+
ll mi=seg.query(0,i);
168+
//cout<<mi spa i spa seg[i] spa (mi>seg[i])<<endl;
169+
if(mi>seg[i])t[i]=true;
170+
}
171+
t[0]=false;
172+
rep(i,0,n){
173+
if(a[i]!=0)t[0]=true;
174+
}
175+
rep(i,0,n+2){
176+
if(!t[i]){
177+
cout<<i+1<<endl;
178+
return 0;
179+
}
180+
}
181+
return 0;
182+
}

0 commit comments

Comments
 (0)