Skip to content

Commit d45ea56

Browse files
committed
LIS Segment Tree Added
1 parent 8167d7b commit d45ea56

File tree

2 files changed

+239
-1
lines changed

2 files changed

+239
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
2+
/*
3+
* Problem : Longest Increasing Subsequence (using Segment Tree)
4+
* */
5+
6+
/** Which of the favors of your Lord will you deny ? **/
7+
8+
#include<bits/stdc++.h>
9+
using namespace std;
10+
11+
#define LL long long
12+
#define PII pair<int,int>
13+
#define PLL pair<LL,LL>
14+
#define F first
15+
#define S second
16+
17+
#define ALL(x) (x).begin(), (x).end()
18+
#define READ freopen("alu.txt", "r", stdin)
19+
#define WRITE freopen("vorta.txt", "w", stdout)
20+
21+
#ifndef ONLINE_JUDGE
22+
#define DBG(x) cout << __LINE__ << " says: " << #x << " = " << (x) << endl
23+
#else
24+
#define DBG(x)
25+
#endif
26+
27+
template<class T1, class T2>
28+
ostream &operator <<(ostream &os, pair<T1,T2>&p);
29+
template <class T>
30+
ostream &operator <<(ostream &os, vector<T>&v);
31+
template <class T>
32+
ostream &operator <<(ostream &os, set<T>&v);
33+
34+
inline void optimizeIO()
35+
{
36+
ios_base::sync_with_stdio(false);
37+
cin.tie(NULL);
38+
}
39+
40+
const int nmax = 2e5+7;
41+
const LL LINF = 1e17;
42+
43+
/**
44+
Segment Tree (Point Update , Range Query)
45+
=========================================
46+
1 based indexing
47+
**/
48+
49+
struct Node
50+
{
51+
int mx;
52+
53+
Node() /// change here
54+
{
55+
mx = 0;
56+
}
57+
58+
void create_leaf(int val) /// change here
59+
{
60+
mx = val;
61+
}
62+
};
63+
64+
Node merge_nodes(Node &a,Node &b) /// change here
65+
{
66+
Node temp;
67+
temp.mx = max(a.mx,b.mx);
68+
69+
return temp;
70+
}
71+
72+
struct SegTree
73+
{
74+
int n;
75+
vector<int>data;
76+
vector<Node>Tree;
77+
78+
SegTree(int n)
79+
{
80+
this->n = n;
81+
int len = n+1;
82+
83+
data = vector<int>(len);
84+
Tree = vector<Node>(len<<2);
85+
}
86+
87+
void build()
88+
{
89+
build(1,1,n);
90+
return;
91+
}
92+
93+
void build(int cur,int start,int end)
94+
{
95+
if(start==end)
96+
{
97+
Tree[cur].create_leaf(data[start]);
98+
return;
99+
}
100+
101+
int mid = (start+end)>>1;
102+
int lc = cur<<1 , rc = lc|1;
103+
104+
build(lc,start,mid);
105+
build(rc,mid+1,end);
106+
107+
Tree[cur] = merge_nodes(Tree[lc],Tree[rc]);
108+
}
109+
110+
void update(int updex,int val)
111+
{
112+
update(1,1,n,updex,val);
113+
}
114+
115+
void update(int cur,int start,int end,int updex,int val)
116+
{
117+
if(start==end)
118+
{
119+
Tree[cur].create_leaf(val);
120+
return;
121+
}
122+
123+
int mid = (start+end)>>1;
124+
int lc = cur<<1 , rc = lc|1;
125+
126+
/// binary search
127+
if(updex<=mid) update(lc,start,mid,updex,val);
128+
else update(rc,mid+1,end,updex,val);
129+
130+
Tree[cur] = merge_nodes(Tree[lc],Tree[rc]); /// bottom up correction after update
131+
}
132+
133+
Node query(int ql,int qr)
134+
{
135+
return query(1,1,n,ql,qr);
136+
}
137+
138+
Node query(int cur,int start,int end,int ql,int qr)
139+
{
140+
if(ql>qr) return Node();
141+
142+
if(end<ql || start>qr) return Node();
143+
144+
if(start>=ql && end<=qr)
145+
{
146+
return Tree[cur];
147+
}
148+
149+
int mid = (start+end)>>1;
150+
int lc = cur<<1 , rc = lc|1;
151+
152+
/// query on both child
153+
Node ansL = query(lc,start,mid,ql,qr);
154+
Node ansR = query(rc,mid+1,end,ql,qr);
155+
156+
return merge_nodes(ansL,ansR);
157+
}
158+
};
159+
160+
int solveLIS(vector<PII>&v)
161+
{
162+
int n = v.size();
163+
164+
vector<PII> sorted = v;
165+
sort(ALL(sorted));
166+
167+
SegTree s(n);
168+
s.build();
169+
170+
for(auto el:sorted)
171+
{
172+
int id = -el.second;
173+
174+
int mx_till_now = s.query(1,id-1).mx;
175+
176+
s.update(id,mx_till_now+1);
177+
}
178+
179+
int lis = s.query(1,n).mx;
180+
return lis;
181+
}
182+
183+
int main()
184+
{
185+
optimizeIO();
186+
187+
int n;
188+
cin>>n;
189+
190+
vector<PII>v(n);
191+
192+
for(int i=0; i<n; i++)
193+
{
194+
int x;
195+
cin>>x;
196+
197+
v[i] = {x,-(i+1)}; /* minus to handle overcounting for duplicates after sorting , so that the latter ones are calculated first */
198+
}
199+
200+
int ans = solveLIS(v);
201+
cout<<ans<<endl;
202+
203+
return 0;
204+
}
205+
/**
206+
5
207+
1 6 2 3 5
208+
**/
209+
210+
template<class T1, class T2>
211+
ostream &operator <<(ostream &os, pair<T1,T2>&p)
212+
{
213+
os<<"{"<<p.first<<", "<<p.second<<"} ";
214+
return os;
215+
}
216+
template <class T>
217+
ostream &operator <<(ostream &os, vector<T>&v)
218+
{
219+
os<<"[ ";
220+
for(T i:v)
221+
{
222+
os<<i<<" " ;
223+
}
224+
os<<" ]";
225+
return os;
226+
}
227+
228+
template <class T>
229+
ostream &operator <<(ostream &os, set<T>&v)
230+
{
231+
os<<"[ ";
232+
for(T i:v)
233+
{
234+
os<<i<<" ";
235+
}
236+
os<<" ]";
237+
return os;
238+
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@
306306
* Longest Increasing Subsequence
307307
- [O(N^2)](Dynamic%20Programming/05%20LIS.cpp)
308308
- [O( NlogN )](Dynamic%20Programming/05.2%20LIS%20(Binary%20Search).cpp) **Binary Search**
309-
- [O( NlogN )]() **Segment Tree** //code not added
309+
- [O( NlogN )](/Dynamic%20Programming/05.3%20LIS%20(Segment%20Tree).cpp) **Segment Tree**
310310
* [Longest Bitonic Subsequence](Dynamic%20Programming/09%20Longest%20Bitonic%20Subsequence.cpp)
311311
* [Increasing Subsequence with Maximum Sum](Dynamic%20Programming/10%20Increasing%20Subsequence%20with%20Maximum%20Sum.cpp)
312312
* [Longest Increasing Index-Dividing Subsequence](Dynamic%20Programming/32%20Longest%20increasing%20index%20dividing%20subsequence.cpp)

0 commit comments

Comments
 (0)