Memory Limit Exceeded with Segment Tree in SPOJ Posters? - memory-management

Given a horizontal section of wall , and N layers of paints applied from co-ordinates Xi to Yi , Output the distinct number of layers visible.
Here is the problem link http://www.spoj.com/problems/POSTERS/
Here is my solution http://ideone.com/gBJKnL
Approach :
I tried solving the problem by lazily updating child node values through a Segment Tree , the most recent value replaces the older one in their lazy updates. This way only the recent paint gets applied into the horizontal cross-section. although the code works fine on custom test cases , It takes a lot of memory and gets aborted by the Online Judge .
#include <iostream>
#include <set>
#include <vector>
#define MAX 10000000+100
typedef long long int ll;
using namespace std;
ll Tree[3*MAX],lazy[MAX*2];
void Update(ll s,ll start,ll end,ll left,ll right,ll value)
{
if(lazy[s]!=0)
{
Tree[s]=(lazy[s]*(end-start+1));
if(start!=end)lazy[2*s+1]=lazy[s],lazy[s*2+2]=lazy[s];
lazy[s]=0;
}
if(start>end||left>end||right<start)return;
if(start>=left&&end<=right)
{
Tree[s] = (value*(end-start+1));
if(start!=end)
{
lazy[2*s+1]=value;
lazy[2*s+2]=value;
}
return ;
}
ll mid=(start+end)/2;
Update(2*s+1,start,mid,left,right,value);
Update(2*s+2,mid+1,end,left,right,value);
Tree[s] = Tree[s*2+1]+Tree[2*s+2];
}
ll Read(ll s,ll start,ll end,ll left,ll right)
{
if(start>end||start>right||end<left)return 0;
if(lazy[s]!=0)
{
Tree[s]=(lazy[s]*(end-start+1));
if(start!=end)
{
lazy[2*s+1]=lazy[s];
lazy[2*s+2]=lazy[s];
}
lazy[s]=0;
}
if(start>=left&&end<=right)return Tree[s];
else return (Read(2*s+1,start,(start+end)/2,left,right)+Read(2*s+2,1+((start+end)/2),end,left,right));
}
int main() {
// your code goes here
ll t;
cin>>t;
while(t--)
{
ll n,z=1,li=-1;
cin>>n;
vector<pair<ll,ll> > b;
for(ll i=0;i<n;i++)
{
ll u,v;
li = max(li,v);
cin>>u>>v;
b.push_back(make_pair(u-1,v-1));
}
for(auto v: b)
Update(0,0,li+2,v.first,v.second,z++);
set<ll> a;
for(ll i=0;i<li+2;i++)cout<<Read(0,0,li+2,i,i)<<" ",a.insert(Read(0,0,li+2,i,i));
cout<<endl;
cout<<a.size()-1<<endl;
}
return 0;
}

Here is how you should be doing it:
#include <bits/stdc++.h>
#define mx 400005
using namespace std;
int tr[mx], lz[mx];
int t, n, l, r;
void update(int node, int s, int e, int l, int r, int val)
{
if(lz[node]!=0)
{
tr[node]=lz[node];
if(s!=e)
{
lz[node*2]=lz[node];
lz[node*2+1]=lz[node];
}
lz[node]=0;
}
if(s>e || r<s || l>e)
return;
if(s>=l && e<=r)
{
tr[node]=val;
if(s!=e)
{
lz[2*node]=val;
lz[2*node+1]=val;
}
return;
}
int m=s+(e-s)/2;
update(2*node,s,m,l,r,val);
update(2*node+1,m+1,e,l,r,val);
tr[node]=val;
//tr[node]=max(tr[2*node],tr[2*node+1]);
}
int query(int node, int s, int e, int l, int r)
{
if(r<s || e<l)
return 0;
if(lz[node]!=0)
{
tr[node]=lz[node];
if(s!=e)
{
lz[node*2]=lz[node];
lz[node*2+1]=lz[node];
}
lz[node]=0;
}
if(l<=s && r>=e)
return tr[node];
int m=s+(e-s)/2;
return query(2*node,s,m,l,r)+query(2*node+1,m+1,e,l,r);
}
int main()
{
//cout << "Hello world!" << endl;
cin>>t;
while(t--)
{
for(int i=0; i<mx; i++) tr[i]=0;
cin>>n;
int lr[n+1][2];
map<int,bool> mark;
vector<int> vec;
//int c=0;
for(int i=0; i<n; i++)
{
cin>>l>>r;
lr[i][0]=l;
lr[i][1]=r;
if(mark[l]==0)
{
vec.push_back(l);
mark[l]=1;
}
if(mark[r]==0)
{
vec.push_back(r);
mark[r]=1;
}
}
sort(vec.begin(), vec.end());
map<int,int> mp;
int c=1;
for(int i=0; i<vec.size(); i++)
mp[vec[i]]=c++;
for(int i=0; i<n; i++)
{
//cout<<mp[lr[i][0]]<<" "<<mp[lr[i][1]]<<"\n";
update(1,1,vec.size(),mp[lr[i][0]],mp[lr[i][1]],i+1);
}
set<int> ans;
for(int i=1; i<=vec.size(); i++)
{
//cout<<query(1,1,vec.size(),i,i)<<" ";
ans.insert(query(1,1,vec.size(),i,i));
}
int k = ans.size();
if(ans.find(0) != ans.end())
k--;
printf("%d\n",k);
}
return 0;
}

Related

iterating through vector array error bs lc first question

class Solution {
public:
int search(vector<int>& nums, int target) {
int count=0;
for(unsigned long i=0; i<nums.size(); ++i){
if(nums[i]==target)
{ return nums[i]; ++count; break;}
}
if(count==0) return -1;
}
};

Quickselect algorithm to find kth-smallest

I am trying to use quickselect to find the kth smallest number. but when I write code which is exactly same as on https://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array/ it give wrong output but when i copy code from GeeksforGeeks it works. I use same header file but it doesn't works.
my code is
#include <bits/stdc++.h>
using namespace std;
int partition(int arr[],int l,int r);
void swapp(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int kthsmallest(int arr[],int l,int r,int k)
{
if(k > 0 && k <= r - l + 1)
{
int pos = partition(arr,l,r);
if(pos-1 == k-1)
{
return arr[pos];
}
if(pos-1 > k-1)
{
return kthsmallest(arr,l,pos-1,k);
}
return kthsmallest(arr,pos+1,r,k-pos+l-1);
}
return INT_MAX;
}
int partition(int arr[],int l,int r)
{
int x = arr[r];
int i = l;
for(int j = l;j<=r-1;j++)
{
if( arr[j] <= x)
{
swapp(&arr[i],&arr[j]);
i++;
}
}
swapp(&arr[i],&arr[r]);
return i;
}
int main()
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
int k;
cin>>k;
cout<<"kth smallest "<<kthsmallest(arr,0,n-1,k);
return 0;
}
You've mixed "1 (one)" and "l (alphabet L)" throughout your code. If you fix that, it works

why this heap sort code fails for some input array

can any body please tell me whats wrong in this code? i have already spent almost 1 day behind this to find out whats wrong in this. this heap sort code fails for some input.
i.e. for input array arr = {1,5,2,4,3,6,0,7,9,8}.
this code should print
{9,8,7,6,5,4,3,2,1,0} but this code gives {5,9,8,7,6,4,3,2,1,0}
#include<iostream>
using namespace std;
void printarr(int *arr,int n)
{
for(int i=0;i<=n;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
void heapify(int *arr,int i,int n)
{
int max=i;
if(arr[max]<arr[(2*i)+1] && (2*i)+1<=n)
max=(2*i)+1;
if(arr[max]<arr[(2*i)+2] && (2*i)+2<=n)
max=(2*i)+2;
if(i!=max)
{
swap(arr[max],arr[i]);
heapify(arr,max,n);
}
}
void buildheap(int *arr,int i,int j)
{
for(;i<=(i+j)/2;i++)
heapify(arr,i,j);
}
int* heapsort(int *arr,int i,int n)
{
buildheap(arr,0,n-1);
int *b,index=0;
b=new int[n];
while(n>=i)
{
b[index++]=arr[i];
arr[i]=arr[n--];
heapify(arr,i,n);
}
return b;
}
int main()
{
int *arr,n;
cout<<"how many elements?"<<endl;
cin>>n;
cout<<"enter elements : "<<endl;
arr=new int [n];
for(int i=0;i<n;i++)
cin>>arr[i];
arr=heapsort(arr,0,n-1);
printarr(arr,n-1);
}
I found 2 errors
You should first check out of bound condition and then compare.
Change if(arr[max]<arr[(2*i)+1] && (2*i)+1<=n) max=(2*i)+1;
To if((2*i)+1<=n && arr[max]<arr[(2*i)+1])
If you are building a heap, You run loop like this. Because of what you have written in heapify
Change void buildheap(int *arr,int i,int j) { for(;i<=(i+j)/2;i++) heapify(arr,i,j); }
To void buildheap(int *arr,int i,int j) { for(i = j/2; i >= 0;i--) heapify(arr,i,j);}
Final Code
#include<iostream>
using namespace std;
void printarr(int *arr,int n)
{
for(int i=0;i<=n;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
void heapify(int *arr,int i,int n)
{
int max=i;
max=(2*i)+1;
if((2*i)+2<=n && arr[max]<arr[(2*i)+2])
max=(2*i)+2;
if(i!=max)
{
swap(arr[max],arr[i]);
heapify(arr,max,n);
}
}
void buildheap(int *arr,int i,int j)
{
for(i = j/2; i >= 0;i--)
heapify(arr,i,j);
}
int* heapsort(int *arr,int i,int n)
{
buildheap(arr,0,n-1);
int *b,index=0;
b=new int[n];
while(n>=i)
{
b[index++]=arr[i];
arr[i]=arr[n--];
heapify(arr,i,n);
}
return b;
}
int main()
{
int *arr,n;
cout<<"how many elements?"<<endl;
cin>>n;
cout<<"enter elements : "<<endl;
arr=new int [n];
for(int i=0;i<n;i++)
cin>>arr[i];
arr=heapsort(arr,0,n-1);
printarr(arr,n-1);
}

distance between any two nodes in a graph(based on edges between them)

The below code in c++ is to find the distance between any two nodes in a graph but there is some logical error where I tried to find but can't. Everything seems to be perfect but I can say that there is something wrong with a break inside if condition inside for loop which is inside while(s.!empty()).
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int find_distance(int link[100][100],int start,int dest,int n,int e)
{
start=start-1;
dest=dest-1;
if(start==dest)return 0;
int visited[100];
int distance;
for(int i=0;i<n;i++)
{
visited[i]=0;
}
stack<int>s;
int k;s.push(start);
visited[start]=1;
bool found=false;
int count =0;
while(!s.empty())
{
k=s.top();
int i;
int check_point=1;
for(i=0;i<n;i++)
{
if(link[k][i]==1 && visited[i]!=1)
{
s.push(i);
count ++;
check_point=0;
if(i==dest)
{
cout<<"found";
found=true;
}
break;
}
}
if(check_point==1)
{
s.pop();
count--;
}
if(found)break;
}
return count;
}
int main()
{
int n,e,a,b;
int link[100][100];
cout<<"enter the number of vertices and edges";
// cin>>n>>e;
n=5;e=4;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
link[i][j]=0;
else
link[i][j]=INT_MAX;
cout<<link[i][j]<<" ";
}
cout<<endl;
}
int input[4][2]={{1,2},{1,3},{2,4},{2,5}};
for(int i=0;i<e;i++)
{
a=input[i][0];
b=input[i][1];
link[a-1][b-1]=1;
link[b-1][a-1]=1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<link[i][j]<<" ";
}
cout<<endl;
}
while(true) {
cout<<endl<<"enter the starting point .. ";
int start;
cin>>start;
int dest;
cout<<endl<<"enter the destination point .. ";
cin>>dest;
int distance = find_distance(link,start,dest,n,e);
cout<<endl<<"distance is "<<distance;
}
return 0;
}

Wrong answer on LIS

I am solving a problem on my college judge where i have to all lis sequences. The n is very small so, i am generating all subsets and if they are increasing and of longest length, i am printing it. What's wrong in my code? Or may be any problem with order?
#include<iostream>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
using namespace std;
int a[100005];
int l[100005];
vector< vector<int> > V;
int main()
{
int n,r,c;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
l[i]=1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(a[i]>a[j]&&l[i]<l[j]+1)
{
l[i]=l[j]+1;
}
}
}
vector<int> v;
r=0;
int cnt=0;
for(int i=0;i<pow(2,n);i++)
{
for(int j=0;j<n;j++)
{
if(i & (1<<j))
{
v.push_back(a[j]);
}
}
int f=0;
if(v.size()==*max_element(l,l+n))
{
int ss=v.size();
for(int x=0;x<ss-1;x++)
{
if(v[x]>=v[x+1])
{
f=-1;
break;
}
}
if(f==0)
{
V.push_back(v);
}
}
v.clear();
}
for(int i=0;i<V.size();i++)
{
for(int j=0;j<V[i].size();j++)
{
cout<<V[i][j];
if(j!=V[i].size()-1)
cout<<" ";
}
cout<<endl;
}
return 0;
}

Resources