From d45ea564b29a6c09c33a86307f13492bd60b2715 Mon Sep 17 00:00:00 2001 From: "Md. Zarif Ul Alam" Date: Wed, 2 Dec 2020 14:29:51 +0600 Subject: [PATCH] LIS Segment Tree Added --- .../05.3 LIS (Segment Tree).cpp | 238 ++++++++++++++++++ README.md | 2 +- 2 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 Dynamic Programming/05.3 LIS (Segment Tree).cpp diff --git a/Dynamic Programming/05.3 LIS (Segment Tree).cpp b/Dynamic Programming/05.3 LIS (Segment Tree).cpp new file mode 100644 index 0000000..0db5f0a --- /dev/null +++ b/Dynamic Programming/05.3 LIS (Segment Tree).cpp @@ -0,0 +1,238 @@ + +/* + * Problem : Longest Increasing Subsequence (using Segment Tree) + * */ + +/** Which of the favors of your Lord will you deny ? **/ + +#include +using namespace std; + +#define LL long long +#define PII pair +#define PLL pair +#define F first +#define S second + +#define ALL(x) (x).begin(), (x).end() +#define READ freopen("alu.txt", "r", stdin) +#define WRITE freopen("vorta.txt", "w", stdout) + +#ifndef ONLINE_JUDGE +#define DBG(x) cout << __LINE__ << " says: " << #x << " = " << (x) << endl +#else +#define DBG(x) +#endif + +template +ostream &operator <<(ostream &os, pair&p); +template +ostream &operator <<(ostream &os, vector&v); +template +ostream &operator <<(ostream &os, set&v); + +inline void optimizeIO() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); +} + +const int nmax = 2e5+7; +const LL LINF = 1e17; + +/** +Segment Tree (Point Update , Range Query) +========================================= +1 based indexing +**/ + +struct Node +{ + int mx; + + Node() /// change here + { + mx = 0; + } + + void create_leaf(int val) /// change here + { + mx = val; + } +}; + +Node merge_nodes(Node &a,Node &b) /// change here +{ + Node temp; + temp.mx = max(a.mx,b.mx); + + return temp; +} + +struct SegTree +{ + int n; + vectordata; + vectorTree; + + SegTree(int n) + { + this->n = n; + int len = n+1; + + data = vector(len); + Tree = vector(len<<2); + } + + void build() + { + build(1,1,n); + return; + } + + void build(int cur,int start,int end) + { + if(start==end) + { + Tree[cur].create_leaf(data[start]); + return; + } + + int mid = (start+end)>>1; + int lc = cur<<1 , rc = lc|1; + + build(lc,start,mid); + build(rc,mid+1,end); + + Tree[cur] = merge_nodes(Tree[lc],Tree[rc]); + } + + void update(int updex,int val) + { + update(1,1,n,updex,val); + } + + void update(int cur,int start,int end,int updex,int val) + { + if(start==end) + { + Tree[cur].create_leaf(val); + return; + } + + int mid = (start+end)>>1; + int lc = cur<<1 , rc = lc|1; + + /// binary search + if(updex<=mid) update(lc,start,mid,updex,val); + else update(rc,mid+1,end,updex,val); + + Tree[cur] = merge_nodes(Tree[lc],Tree[rc]); /// bottom up correction after update + } + + Node query(int ql,int qr) + { + return query(1,1,n,ql,qr); + } + + Node query(int cur,int start,int end,int ql,int qr) + { + if(ql>qr) return Node(); + + if(endqr) return Node(); + + if(start>=ql && end<=qr) + { + return Tree[cur]; + } + + int mid = (start+end)>>1; + int lc = cur<<1 , rc = lc|1; + + /// query on both child + Node ansL = query(lc,start,mid,ql,qr); + Node ansR = query(rc,mid+1,end,ql,qr); + + return merge_nodes(ansL,ansR); + } +}; + +int solveLIS(vector&v) +{ + int n = v.size(); + + vector sorted = v; + sort(ALL(sorted)); + + SegTree s(n); + s.build(); + + for(auto el:sorted) + { + int id = -el.second; + + int mx_till_now = s.query(1,id-1).mx; + + s.update(id,mx_till_now+1); + } + + int lis = s.query(1,n).mx; + return lis; +} + +int main() +{ + optimizeIO(); + + int n; + cin>>n; + + vectorv(n); + + for(int i=0; i>x; + + v[i] = {x,-(i+1)}; /* minus to handle overcounting for duplicates after sorting , so that the latter ones are calculated first */ + } + + int ans = solveLIS(v); + cout< +ostream &operator <<(ostream &os, pair&p) +{ + os<<"{"< +ostream &operator <<(ostream &os, vector&v) +{ + os<<"[ "; + for(T i:v) + { + os< +ostream &operator <<(ostream &os, set&v) +{ + os<<"[ "; + for(T i:v) + { + os<