Range minimum Query - c++

This is rmq using segment tree.
But i am not getting correct output can anybody tell me where i am wrong.
`
#include<iostream>
#include<cmath>
#define inf 1e9
using namespace std;
int get_mid(int a,int b){
return a+(b-a)/2;
}
int min(int a,int b){
int temp=(a<b)?a:b;
return temp;
}
int get_min_util(int str[],int beg,int end,int l,int r,int i){
if(l<=beg && r>=end)
return str[i];
if(l>end || r<beg){
return 0; ////////c1
}
int mid=get_mid(beg,end);
return (get_min_util(str,beg,mid,l,r,2*i+1),get_min_util(str,mid+1,end,l,r,2*i+2));
}
int get_min(int str[],int len,int l,int r){
if(l<0 || r>len-1 || l>r){
return 0;
}
else
return get_min_util(str,0,len-1,l,r,0);
}
int build_rmq_arr_util(int str[],int beg,int end,int big_arr[],int i){
if(beg==end){
big_arr[i]=str[beg];
return big_arr[i];
}
int mid=get_mid(beg,end);
big_arr[i]=min(build_rmq_arr_util(str,beg,mid,big_arr,2*i+1),build_rmq_arr_util(str,mid+1,end,big_arr,2*i+2));
return big_arr[i];
}
int*bulid_rmq_arr(int str[],int len){
int temp=ceil(log2(len));
temp=2*pow(2,temp)-1;
int *big_arr=new int[temp];
build_rmq_arr_util(str,0,len-1,big_arr,0);
return big_arr;
}
void pop(int arr[],int size){
for(int i=0;i<size;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main(){
int str[]={1,2,3,4,5,6};
int len=sizeof(str)/sizeof(int);
int *rmq_arr;
rmq_arr=bulid_rmq_arr(str,len);
//pop(rmq_arr,3*len);
cout<<get_min(rmq_arr,len,1,2);
}
`
output of this code:
0
expected output in range 1-2 is 2
function get_min_util return 0 from if condition where comment ////////c1 is written

problem is in get_min_util().It should return infinity when not in range.Also you have to return minimum of left and right child.
int get_min_util(int str[],int beg,int end,int l,int r,int i){
if(l<=beg && r>=end)
return str[i];
if(l>end || r<beg){
return inf; ////////c1
}
int mid=get_mid(beg,end);
return min(get_min_util(str,beg,mid,l,r,2*i+1),get_min_util(str,mid+1,end,l,r,2*i+2));
}

Related

Why isn't my binary search giving me a result for the first element?

I'm trying to return the index of the element to be searched. All the elements are being detected except the first element. What's wrong? Why is the function not returning index 0?
using namespace std;
int binsearch(int a[],int x,int y)
{
int low=a[0];
int high=a[x-1];
while(low<=high)
{
int mid=(low+high)/2;
if(y==a[mid])
{
return mid;
}
else if(y>a[mid])
{
low=mid+1;
}
else
{
high=mid-1;
}
}
return -1;
}
int main()
{
int a[]={1,2,3,4,5,6,7,8,9};
int x=sizeof(a)/sizeof(a[0]);
int y;
cin>>y;
cout<<binsearch(a,x,y);
}
int low=a[0];
int high=a[x-1];
should be
int low=0;
int high=x-1;

Change Karnaugh Map simplifier from SOP to POS result

It's my program to simplify Karnough map. I need to change it from SOP to POS for university project. I changed already signs from + to * and from * to +. All i have to do now is to make it read zero-s from text file instead of one's. i tried everything to solve that problem, but i have no idea. I have got two txt files, one with input and one with output. At this moment i need to put in input 0's instead of 1's and in the other side to, to make it work. Please help me, my life depends of that
#include <iostream>
#include <fstream>
#include <cmath>
#include <windows.h>
using namespace std;
//?????
int pow2(int n) // ??2?????,2^n
{
int result=1
;
while(n>0)
result*=2,n--;
return result;
}
int combination(int n,int r) // ?????C_n^r,? n! / ((n-r)!*(r)!)
{
int fm=1,fz=1;
for(int i=1;i<=r;i++,n--)
{
fm*=i;
fz*=n;
}
return fz/fm;
}
void d2b(int d,char* b,int n) // ???????,??????d???????????b?
{
for(n--;n>=0;n--)
{
b[n]='0'+d%2;
d/=2;
}
}
int ispair(char* a1,char* a2,int n) // ????????????????
{
int x,y=0;
for(int i=0;i<n;i++)
if(a1[i]!=a2[i])
x=i,y++;
if(y==1) return x;
else return-1;
}
bool issame(char* a1,char* a2,int n) // ????
{
for(int i=0;i<n;i++)
if(a1[i]!=a2[i])
return 0;
return 1;
}
int left1(char* a,int N) // ???????????,??????1,??????
{
for(int i=0;i<N;i++)
if(a[i]=='1')
return i;
return -1;
}
void copy(char* a1,char* a2,int n) // ??????
{
for(int i=0;i<n;i++)
a2[i]=a1[i];
}
bool isinside(int x,char* a,int n) // ???x????????a?
{
for(n--;n>=0;n--)
{
if(a[n]!='x' && a[n]!=(char)('0'+x%2))
return 0;
x/=2;
}
return 1;
}
void output(fstream& file,char* a,int n)
{
for(int i=0;i<n;i++)
{
if(i==0)file<<'(';
if(a[i]=='0'||a[i]=='1')
{
if(a[i]=='0') file<<'¬'<<(char)('a'+i);
if(a[i]=='1') file<<(char)('a'+i);
if(a[i+1]=='0'||a[i+1]=='1'||a[i+2]=='0'||a[i+2]=='1'||a[i+3]=='0'||a[i+3]=='1')
{
file<<'+';
}
else{
file<<')';
}
}
else{}
;
}
file<<'*';
}
int count(char* table,char* a,int n,int N) // ??,????????1???????????a?
{
int counter=0;
for(int i=0;i<N;i++)
{
if(table[i]!='1') continue;
if(isinside(i,a,n)) counter++;
}
return counter;
}
void clean(char* table,char* a,int n,int N) // ??????????????????1,???x
{
for(int j=0;j<N;j++)
if(isinside(j,a,n))
table[j]='x';
}
int main()
{
SetConsoleTitle("???-???????????");
system("color 06");
//????
fstream inputFile("input.txt",ios::in); //??????????input.txt
int valNum; //???
inputFile >> valNum; // ???????????
cout<<"\n ????????: "<<valNum;
cout<<"\n ?????????:\n";
int minTermLength=pow2(valNum); // ??????????2^valNum?
char* minTermExpression=new char[minTermLength]; // ???????????????
int lineOff = pow2(ceil(double(valNum)/2));
// ???????
if (inputFile.is_open())
{
for(int i=0;i<minTermLength;i++) // ?????
{
inputFile>>minTermExpression[i];
if(i%lineOff == 0&&(i!=0))
cout<<"\n";
cout<<"\t"<<minTermExpression[i];
}
inputFile.close();
}
// ??????
else{
cout<<"\n ??input.txt??,???????";
return 0;
}
// ?implication????????
char*** implication=new char**[valNum]; // ????
int nonZeroNum=1;
for(int i=0;i<minTermLength;i++)
if(minTermExpression[i]!='0') // ?????ON???DC?????????
nonZeroNum++;
for(int i=0;i<valNum;i++) // i-??,???????3?,i=0???????,i=1???,i=2???
{
if(pow2(i)>nonZeroNum)break;
int x=pow2(i-1)*combination(nonZeroNum,pow2(i));
implication[i]=new char*[x];
for(int j=0;j<x;j++)
implication[i][j]=new char[valNum];
}
//?????????
int* countNum=new int[valNum+1];
countNum[0]=0;
for(int i=0;i<minTermLength;i++)
if(minTermExpression[i]!='0') // ???0?
{
d2b(i,implication[0][countNum[0]],valNum); // ??????????implication[0]???
countNum[0]++;
}
int isOptimal=0;
while(countNum[isOptimal]>0) // ??????????
{
countNum[isOptimal+1]=0;
for(int i=0;i<countNum[isOptimal]-1;i++)
for(int j=i+1;j<countNum[isOptimal];j++)
{
int x=ispair(implication[isOptimal][i],implication[isOptimal][j],valNum); // ??????????
if(x==-1) continue;
copy(implication[isOptimal][i],implication[isOptimal+1][countNum[isOptimal+1]],valNum);// ???implication??
implication[isOptimal+1][countNum[isOptimal+1]][x]='x'; // ??????????,?????????x,???????????
countNum[isOptimal+1]++;
}
for(int i=0;i<countNum[isOptimal+1]-1;i++)
for(int j=i+1;j<countNum[isOptimal+1];j++)
if(issame(implication[isOptimal+1][i],implication[isOptimal+1][j],valNum)) // ??????
{
for(int k=j;k<countNum[isOptimal+1]-1;k++)
copy(implication[isOptimal+1][k+1],implication[isOptimal+1][k],valNum);
countNum[isOptimal+1]--;
}
isOptimal++;
}
isOptimal--;
//???????
fstream outputFile("output.txt",ios::out);
outputFile<<"F=";
while(left1(minTermExpression,minTermLength)>=0) //?minTermExpression???1
{
bool flag=0; // ???,????
for(int i=0;i<minTermLength&&flag==0;i++)
{
if(minTermExpression[i]!='1') continue;
int counter=0,recorder;
for(int j=0;j<countNum[isOptimal];j++)
if(isinside(i,implication[isOptimal][j],valNum))
counter++,recorder=j;
if(counter!=1) continue;
output(outputFile,implication[isOptimal][recorder],valNum);
clean(minTermExpression,implication[isOptimal][recorder],valNum,minTermLength);
flag=1;
}
if(flag==1) continue;
int termMaxInclude=0;
int recorder=0;
for(int i=0;i<countNum[isOptimal];i++) // ??????????,???????????1???,??????
if(count(minTermExpression,implication[isOptimal][i],valNum,minTermLength)>termMaxInclude)
termMaxInclude=count(minTermExpression,implication[isOptimal][i],valNum,minTermLength),recorder=i;
if(termMaxInclude==0) {isOptimal--; continue;}
output(outputFile,implication[isOptimal][recorder],valNum);
clean(minTermExpression,implication[isOptimal][recorder],valNum,minTermLength);
}
outputFile.close();
// ?????
outputFile.open("output.txt",ios::in);
char finalExpression[201];
outputFile.getline(finalExpression,200);
outputFile.close();
int termMaxInclude=0;
for(;finalExpression[termMaxInclude]!='\0';termMaxInclude++);
finalExpression[termMaxInclude-1]='\0';
outputFile.open("output.txt",ios::out);
outputFile<<finalExpression;
outputFile.close();
cout<<"\n??????????????";
cout<<"\n ??????,??????!";
cin.get();
return 0;
}
The zeros are simply those not in the ones list.

merge sort sorting partially

for input 6,2,9,1,5,8 i'm getting 1,2,6,9,5,8.This algorithm is written based on https://gist.github.com/mycodeschool/9678029#file-mergesort_c-c-L28
please help me in getting 1,2,5,6,8,9 as the output also point out the mistake here.Thanks in advance.
#include<iostream>
using namespace std;
void merge(int a[],int l[],int lc,int r[],int rc){
int i,j,k;
i=0;j=0;k=0;
while(i<lc && j<rc){
if(l[i]<r[j]){
a[k++]=l[i++];
}
else{
a[k++]=r[j++];
}
while(i<lc){
a[k++]=l[i++];
}
while(j<rc){
a[k++]=r[j++];
}
}
}
void mergesort(int a[],int n){
int mid;
if (n<2){
return;
}
mid=n/2;
int l[mid],r[n-mid];
for(int i=0;i<mid;i++){
l[i]=a[i];
}
for(int i=mid;i<n;i++){
r[i-mid]=a[i];
}
mergesort(l,mid);
mergesort(r,n-mid);
merge(a,l,mid,r,n-mid);
}
int main(){
int a[]={6,2,9,1,5,8};
int n=6;
mergesort(a,n);
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
}
your problem is that is that these loops
while(i<lc){
a[k++]=l[i++];
}
while(j<rc){
a[k++]=r[j++];
}
are inside this loop while(i<lc && j<rc) and they should be outside it as you copy the rest of a[] if b[] is done while a[] has some elements and like wise for b[] and this is the whole merge function
void merge(int a[],int l[],int lc,int r[],int rc)
{
int i,j,k;
i=0;
j=0;
k=0;
while(i<lc && j<rc)
{
if(l[i]<r[j])
{
a[k++]=l[i++];
}
else
{
a[k++]=r[j++];
}
}
while(i<lc)
{
a[k++]=l[i++];
}
while(j<rc)
{
a[k++]=r[j++];
}
}

why the below merge sort code doesnt work?

What should be changed in the below code? It shows the following error
ERROR: ld.so: object '/home/bot/funcs.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
Error in `/home/bot/dcb7b4b8f54571a4467c2113b7856878': free(): invalid next size (fast): 0x0000000000c350b0
#include <iostream>
using namespace std;
int merge(int *left,int nl,int *right,int nr,int *a)
{
int i=0,j=0,k=0;
while(i<nl && j<nr)
{
if(left[i]<right[j])
{
a[k]=left[i];
i++;
}
else
{
a[k]=right[j];
j++;
}
k++;
}
while(i<nl)
{
a[k]=left[i];
i++;
}
while(j<nr)
{
a[k]=right[j];
j++;
}
}
int mergesort(int *a,int n)
{
if(n<2) return 0;
int mid=n/2;
int *left=new int[mid];
int *right=new int[n-mid];
for(int i=0;i<=mid-1;i++)
{
left[i]=a[i];
}
for(int i=mid;i<=n-1;i++)
{
right[i]=a[i];
}
mergesort(left,mid);
mergesort(right,n-mid);
merge(left,mid,right,n-mid,a);
delete[]left;
delete[]right;
}
int main() {
//code
int a[]={10,7,8,9,4,2,3,6,5,1};
int n=sizeof(a)/sizeof(a[0]);
mergesort(a,n);
for(int i=0;i<10;i++)
{
cout<<a[i]<<"\t";
}
return 0;
}
Fixes noted in comments, seems to be working now. A one time allocation of a temp array either in main or in a helper function would be faster. Using mutually recursive functions (one merges AtoA, the other merges AtoTemp, they call each other), eliminates having to copy data. I can post an example later if wanted. Bottom up merge sort would be slightly faster.
#include <iostream>
using namespace std;
// fix return type to void
void merge(int *left,int nl,int *right,int nr,int *a)
{
int i=0,j=0,k=0;
while(i<nl && j<nr)
{
if(left[i]<right[j])
{
a[k]=left[i];
i++;
}
else
{
a[k]=right[j];
j++;
}
k++;
}
while(i<nl)
{
a[k]=left[i];
i++;
k++; // fix
}
while(j<nr)
{
a[k]=right[j];
j++;
k++; // fix
}
}
// fix return type to void
void mergesort(int *a,int n)
{
if(n<2) return; // fix: change return type to void
int mid=n/2;
int *left=new int[mid];
int *right=new int[n-mid];
for(int i=0;i<=mid-1;i++)
{
left[i]=a[i];
}
for(int i=mid;i<=n-1;i++)
{
right[i-mid]=a[i]; // fix
}
mergesort(left,mid);
mergesort(right,n-mid);
merge(left,mid,right,n-mid,a);
delete[]left;
delete[]right;
}
int main() {
//code
int a[]={10,7,8,9,4,2,3,6,5,1};
int n=sizeof(a)/sizeof(a[0]);
mergesort(a,n);
for(int i=0;i<10;i++)
{
cout<<a[i]<<"\t";
}
cout << endl; // added this not needed
return 0;
}
Cleanup, changed output to not use tabs:
#include <iostream>
#include <iomanip> // for std::setw()
using namespace std;
void merge(int *left,int nl,int *right,int nr,int *a)
{
int i=0,j=0,k=0;
while(i<nl && j<nr)
{
if(left[i]<right[j])
a[k++]=left[i++];
else
a[k++]=right[j++];
}
while(i<nl)
a[k++]=left[i++];
while(j<nr)
a[k++]=right[j++];
}
void mergesort(int *a,int n)
{
if(n<2)
return;
int mid=n/2;
int *left=new int[mid];
int *right=new int[n-mid];
for(int i=0;i<=mid-1;i++)
left[i]=a[i];
for(int i=mid;i<=n-1;i++)
right[i-mid]=a[i];
mergesort(left,mid);
mergesort(right,n-mid);
merge(left,mid,right,n-mid,a);
delete[]left;
delete[]right;
}
int main() {
int a[]={10,7,8,9,4,2,3,6,5,1};
int n=sizeof(a)/sizeof(a[0]);
mergesort(a,n);
for(int i=0;i<10;i++)
cout<<setw(2)<<a[i]<<" "; // 2 digit field output
cout << endl;
return 0;
}
You should use std::vector instead of raw pointer:
typedef std::vector<int> ivector;
void merge( const ivector &l, const ivector &r, ivector &to )
{
ivector_const::iterator il = l.begin();
ivector_const::iterator ir = r.begin();
ivector::iterator ito = to.begin();
while( true ) {
if( il == l.end() ) {
if( ir == r.end() )
return;
*ito++ = *ir++;
} else {
if( ir == r.end() || *il < *ir )
*ito++ = *il++;
else
*ito++ = *ir++;
}
}
}
void mergesort( ivector &v )
{
if(v.size()<2) return;
ivector::iterator imid = v.begin() + v.size() / 2;
ivector left( v.begin(), imid );
ivector right( imid, v.end() );
mergesort(left);
mergesort(right);
merge( left, right, v );
}
int main() {
//code
ivector a ={10,7,8,9,4,2,3,6,5,1};
mergesort(a);
for(size_t i=0;i<a.size();i++)
{
cout<<a[i]<<"\t";
}
return 0;
}
Note: I did not validate your algorithm just rewrote it with std::vector instead of raw pointer. You can notice how simpler your function become when you use proper data type.

KGSS - Maximum Sum (SPOJ)

I solved the given problem as shown in the code
But I am getting wrong answer.
I used the Segment tree approach.
node contains max1 (maximum no in given range) and sum(max sum of two no in given range).
Please help.
#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std;
struct node
{
long long int max1;
long long int sum;
};
node constructstutil(int a[],node tree[],int st,int end,int index)
{
if(st==end)
{
tree[index].max1=a[st];
tree[index].sum=a[st];
return tree[index];
}
int mid=(st+end)/2;
node i=constructstutil(a,tree,st,mid,2*index+1);
node j=constructstutil(a,tree,mid+1,end,2*index+2);
int max2=i.max1+j.max1;
if(max2> i.sum&& max2>j.sum)
{
tree[index].max1=max(i.max1,j.max1);
tree[index].sum=max2;
return tree[index];
}
else
{
if(i.sum>j.sum)
{
tree[index].max1=max(i.max1,j.max1);
tree[index].sum= i.sum;
return tree[index];
}
else
{
tree[index].max1=max(i.max1,j.max1);
tree[index].sum=j.sum;
return tree[index];
}
}
}
node* constructst(int a[],int n)
{
int size,k;
k=(int)(ceil(log2(n)));
size=2*(int)pow(2,k)+1;
node* tree=new node[size];
constructstutil(a,tree,0,n-1,0);
return tree;
}
void updatevalueutil(int a[],node tree[],int s,int e,int i,int val,int index)
{
if(i>e||i<s)
return;
if(s==e&& s== i)
{
tree[index].max1=val;
tree[index].sum=val;
return;
}
int mid=(s+e)/2;
updatevalueutil(a,tree,s,mid,i,val,2*index+1);
updatevalueutil(a,tree,mid+1,e,i,val,2*index+2);
int i1=2*index+1;
int i2=2*index+2;
int max2=tree[i1].max1+tree[i2].max1;
if(max2> tree[i1].sum && max2>tree[i2].sum)
{
tree[index].max1=max(tree[i1].max1,tree[i2].max1);
tree[index].sum=max2;
}
else
{
if(tree[i1].sum>tree[i2].sum)
{
tree[index].max1=max(tree[i1].max1,tree[i2].max1);
tree[index].sum= tree[i2].sum;
}
else
{
tree[index].max1=max(tree[i1].max1,tree[i2].max1);
tree[index].sum=tree[i2].sum;
}
}
}
void updatevalue(int a[],int n,node tree[],int i,int val)
{
a[i]=val;
updatevalueutil(a,tree,0,n-1,i,val,0);
}
node queryutil(int a[],node tree[],int qs,int qe,int s,int e,int index)
{
node t;
t.max1=t.sum=0;
if(qs<=s&&qe>=e)
return tree[index];
if(qs>e || qe<s || qs>qe)
return t ;
int mid=(s+e)/2;
node i=queryutil(a,tree,qs,qe,s,mid,2*index+1);
node j=queryutil(a,tree,qs,qe,mid+1,e,2*index+2);
int max2=i.max1+j.max1;
if(max2> i.sum&& max2>j.sum)
{
t.sum=max2;
t.max1=max(i.max1,j.max1);
return t;
}
else
{
if(i.sum>j.sum)
{
t.sum= i.sum;
t.max1=max(i.max1,j.max1);
return t;
}
else
{
t.sum=j.sum;
t.max1=max(i.max1,j.max1);
return t;
}
}
}
long long int query(int a[],int n,node tree[],int qs,int qe)
{
int s=0;
int e=n-1;
node t= queryutil(a,tree,qs,qe,s,e,0);
return t.sum;
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
node* tree=constructst(a,n);
int k;
scanf("%d",&k);
while(k--)
{
char ch;
int index,val;
int qs,qe,ans;
cin>>ch;
if(ch=='U')
{
scanf("%d %d",&index,&val);
updatevalue(a,n,tree,index-1,val);
}
else if (ch=='Q')
{
scanf("%d %d",&qs,&qe);
long long int ans=query(a,n,tree,qs-1,qe-1);
printf("%lld\n",ans);
}
}
}