I was practising dynamic programming on SPOJ. I am stuck on this problem named AGS. Below is my code. It is giving runtime error on SPOJ but is running perfectly fine on my computer. Please help
#include<stdio.h>
long long mypow(long long base,long long exp,long long mod,long long log[])
{
if(log[exp]!=0)
return log[exp];
if(exp==0)
return 1;
if(exp==1)
return base%mod;
long long ans = ((base%mod) * mypow(base,exp-1,mod,log))%mod;
log[exp]=ans;
return ans;
}
long long gpsum(long long r,long long k,long long mod,long long log[])
{
if(k==0)
return 1;
if(k==1)
return 1+r;
long long ans=(mypow(r,k,mod,log)+gpsum(r,k-1,mod,log))%mod;
return ans;
}
int main()
{
long long i,t,k,a,d,r,n,mod,p,q,ans;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld %lld",&a,&d,&r);
scanf("%lld %lld",&n,&mod);
long long log[n/2];
for(i=0;i<n/2;i++)
log[i]=0;
if(n==1)
{
ans=a;
}
else if(n%2==0)
{
k=(n-2)/2;
p=mypow(r,k,mod,log);
q=gpsum(r,k,mod,log);
ans=(((p%mod)*(a%mod))%mod+((q%mod)*(d%mod))%mod)%mod;
}
else
{
k=(n-3)/2;
p=r*mypow(r,k,mod,log);
q=r*gpsum(r,k,mod,log);
ans=(((p%mod)*(a%mod))%mod+((q%mod)*(d%mod))%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
It looks like the line long long log[n/2]; causing the error. For n = 12345678 (from the sample input in the comments) it will try to allocate around 6M of long long which is about 50Mb on the stack. Which is, I am guessing, too big for the online multi user compilers. The following code will prove this claim:
#include<stdio.h>
#define MAX 7000000
int main()
{
volatile long long v[MAX];
long i;
for ( i=0; i<MAX; i++ )
v[i]=i+1;
printf("Hello");
return 0;
}
The value of MAX as stated will give the error on ideone. Reducing the value, say to 700000 will remove the error (don't mind the volatile and the loop exercises, they are there to trick on optimizer).
A possible solution would be allocating this memory statically, as a global variable - outside the main function, such that it will go to the .data section, and not to the stack. This solution:
#include<stdio.h>
#define MAX 7000000
volatile long long v[MAX];
int main()
{
long i;
for ( i=0; i<MAX; i++ )
v[i]=i+1;
printf("Hello");
return 0;
}
works just fine even with larger numbers.
Related
Here is my code, for some reason I have to use unsigned long. The gdb tells me that I have
seg fault. Can one can help me? I could not find it by myself. The most interesting thing is that if I change the type to int from unsigned long, there is no seg fault.
Code is here:
#include <stdio.h>
int counting_Sort (unsigned long ary[], unsigned long array_size,unsigned long max){
unsigned long counting[max+1];
unsigned long j;
for(j=0;j<max+1;j++){
counting[j]=0;//initize to zero
}
unsigned long i;
for(i=0;i<array_size;i++){
counting[ary[i]]++;
}
unsigned long q;
for(q=1;q<max+1;q++){
counting[q]=counting[q-1]+counting[q];
}
for(q=0;q<max+1;q++){
counting[q]=counting[q]-1;
}
unsigned long outputAry[array_size];
unsigned long d;
for(d=(array_size-1); d>=0;d--){
outputAry[counting[ary[d]]]=ary[d];// SEG FAULT IS HERE
counting[ary[d]]--;//AND HERE
}
unsigned long m;
//for(m=0; m<array_size;m++){
// printf("%lu\n",outputAry[m]);
// }
return 0;
}
int main(){
unsigned long array[7]={2,6,4,0,1,7,9};
printf("before sorting the order is: \n");
unsigned long i;
for(i=0;i<7;i++){
printf("%lu\n",array[i]);
}
printf("after sorting, the new order is: \n");
counting_Sort(array,7,9);
getchar();
return 0;
}
You've found the place, just not the reason.
unsigned long d;
for(d=(array_size-1); d>=0;d--){
d is an unsigned integer, which means d>=0 is always true. The loop never ends, and that's the reason of segmentation fault.
One way is to change d to a singed type:
int d;
But if that's not what you want, change the for loop to:
for (d = 0; d <= array_size - 1; d++){
I had written this code which has the recursive function differ, when I run it, using the printf statements I notice that the code executes in the proper direction and I get the required value printed by the printf statement at the end of differ function but that value is not immediately returned instead the recursion goes again in the reverse direction and returns a wrong value. I have been struggling to debug it but I do not understand why it does not return immediately after it executes the last printf statement. Please help!!
To run enter:
5 3 1
0 3 8 5 12
1 3
as the input
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
long long int df;
long long max(long long int a,long long int b)
{
long long int maxi;
maxi = a>b ? a:b;
return maxi;
}
long long min(long long int x,long long int y,long long int *a)
{
long long int mini;
mini = a[x]<a[y] ? (x+1):(y+1);
return mini;
}
long long differ(long long int n1,long long int n2,long long int *a,long long int k,long long int n)
{
long long int df,i;
df=a[n1-1]-a[n2-1];
df=abs(df);
printf("%lld\n",df);
if(df>k)
{
for(i=0;i<n;i++)
{
if(max(a[n1-1],a[n2-1])>a[i] && (max(a[n1-1],a[n2-1])-a[i])<=k)
{
printf("%lld %lld\n",a[i],a[min(n1-1,n2-1,a)-1]);
differ(i+1,min(n1-1,n2-1,a),a,k,n);
return df; //Even this does not work
}
}
}
printf("%lld 90909\n",df);/*This does print a required value but changes again and returns a wrong value finally.*/
return df;
}
int main()
{
long long int n,k,p,f1,f2,d=0,i,j;
scanf("%lld",&n);
long long int a[n];
scanf("%lld",&k);
scanf("%lld",&p);
for(i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
while(p-- > 0)
{
scanf("%lld",&f1);
scanf("%lld",&f2);
printf("%lld df\n",d);
d = differ(f1,f2,a,k,n);
printf("%lld diff",d);
if(d<=k)
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
return 0;
}
Assigning the recursive function to df would solve the problem, that is
df=differ(i+1,min(n1-1,n2-1,a,k,n);
Hope it helps someone who is struggling with this small mistake during recursion.
This question already has answers here:
Big array gives segmentation error in C
(4 answers)
Closed 9 years ago.
This program is to find the prime number which is is the sum of most number of consecutive prime numbers. When I set the value of LIMIT to 50 100 or even 1000, the correct values are obtained. But if I take the value of LIMIT greater than 0.3 million the program crashes. What is the reason behind this problem and how can I solve it?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define LIMIT 300000
//binary search function
int Bsearch(long long int *arr,long long int low,long long int high,long long int search)
{
if(high<low)
return 0;
long long int mid = (low+high)/2;
if(search<arr[mid])
{return(Bsearch(arr,low,mid-1,search));}
else if(search>arr[mid])
{return(Bsearch(arr,mid+1,high,search));}
else if(search==arr[mid]) return 1;
else return 0;
}
int main()
{
long int arr[LIMIT];
arr[0]=0;arr[1]=1;
for(long long int i=2;i<=LIMIT;i++)
{arr[i]=1;}
long long index=2;
for(long long int i=3;i<=LIMIT;i++,index++)
{
for(long long int j=2;j<=sqrt(i);j++)
{
if(i%j==0)
{arr[index]=0;}
}
}
long long int count=0;
//calculate total primes
for(long int A=0;A<LIMIT;A++)
{
if(arr[A]==1)
count++;
}
//all primes stored in seperate primes array
long long int primes[count];
for(long int A=0,index=0;A<LIMIT;A++)
{
if(arr[A]==1)
{
primes[index++]=A+1;
}
}
long long int primes_sum[count];
primes_sum[0]=primes[0];
for(long long int B=1;B<count;B++)
{primes_sum[B]=primes_sum[B-1]+primes[B];}
for(long long int i =0;i<(sizeof(primes)/sizeof(long long int));i++)
{
printf("\nprime number : %lld\tprimes_sum : %lld",primes[i],primes_sum[i]);
}
struct ultimata
{
long long int num_of_primes;
long long int prime_number;
}final;
final.num_of_primes=0;final.prime_number=0;
for(long long int j=(sizeof(primes_sum)/sizeof(long long int))-1;j>=2;j--)
{
for(long long int i=j-2;i>=1;i--)
{
long long int search_term = primes_sum[j]-primes_sum[i];
printf("\nsearch term : %lld (primes_sum[%lld]-primes_sum[%lld])",search_term,j,i);
if(search_term>LIMIT)
break;
if(Bsearch(primes,0,(sizeof(primes)/sizeof(long long int)),search_term))
{
printf("\nfound! : %lld terms : %lld",search_term,j-i-1);
if((j-i-1)>final.num_of_primes)
{
printf("\nfound! : %lld",search_term);
final.prime_number=search_term;
final.num_of_primes=j-i-1;
}
}
}
}
printf("Largest prime number : %lld",final.prime_number,final.num_of_primes);
return 0;
}
I think one of your problems is in these lines (multiple times in other places, too):
long int arr[LIMIT];
...
for(long long int i=2;i<=LIMIT;i++)
{arr[i]=1;}
Your array has LIMIT entries, but you try to write to entry LIMIT+1. C starts with array index 0 and ends with size-1.
I don't know why it works for smaller values of LIMIT.
We are given an array a[1..N]. For each element a[i] in the array, we note down the sum of all the elements which are smaller and occur before the present element. I need to calculate the total sum for every element in the array.
Constraints:
1<=N<=10^5
All elements will be between 0 and 10^6.
Here is the link to my question: http://www.spoj.com/problems/DCEPC206/. I'm using the approach shown below, but I'm getting TIME LIMIT EXCEEDED error on SPOJ. How can I improve my solution?
include
int main()
{
long n,a[100000],i,j,sum;
printf("enter the number of elements");
scanf("%ld",&n);
printf("enter the elements of the array");
for(i=0;i<n;i++)
scanf("%ld",&a[i]);
sum=0;
for(i=1;i<n;i++)
for(j=i-1;j>=0;j--)
if(a[i]>a[j])
sum+=a[j];
printf("\n%ld",sum);
return 0;
}
Yours is a trivial implementation which takes time of the order of O(n^2) but for the solution to get accepted you have to use Divide and Conquer as you do in Merge Sort which takes only O(NLogN) time compared to simpler sorting algorithms like Bubble Sort,etc.
For this you simply can change the Mergesort implementation a little bit simply by adding 2-3 lines of code in it. For understanding this better go through question of counting inversions in an array.(http://www.geeksforgeeks.org/counting-inversions/) Then you will realize you simply have to consider pairs opposite in nature to inversion and add all the smaller elements of all such pairs . For example - in an array 1,4,2,5 consider 4,2 is inversion but we have to consider pairs like 2,5 and 1,2 to get the solution. In every such pair keep adding the left no. ( Think hard about how it is doing our job !! )
For your reference go thoroughly through this merge sort code in which i have small changes to get a correct accepted solution.(sum variable stores the resultant value)
#include <stdio.h>
#include <stdlib.h>
long long int sum;
void merge(long long int c[],long long int arr[],long long int start,long long int middle,long long int end)
{
long long int i=0,j=start,k=middle;
while((j<middle)&&(k<end))
{
if(arr[j]<arr[k])
{
sum=sum+((end-k)*arr[j]);
c[i]=arr[j];
i++;j++;
}
else
{
c[i]=arr[k];
i++;k++;
}
}
while(j<middle)
{
c[i]=arr[j];
i++;
j++;
}
while(k<end)
{
c[i]=arr[k];
i++;
k++;
}
}
void msort(long long int arr[],long long int start,long long int end)
{
long long int middle=(start+end)/2;
if((end-start)==1)
{ return ;
}
msort(arr,start,middle);
msort(arr,middle,end);
long long int *c;
c=(long long int*)malloc(sizeof(long long int)*(end-start));
merge(c,arr,start,middle,end);
long long int i,j=0;
for(i=start;i<end;i++)
{
arr[i]=c[j];
j++;
}
}
void swap (long long int x[],long long int m,long long int n)
{
long long int t= x[m];
x[m]=x[n];
x[n]=t;
}
int main()
{
int t,i;
long long int n,*arr,j;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%lld",&n);
arr = ( long long int * ) malloc ( sizeof(long long int) * n + 10);
for(j=0;j<n;j++)
{
scanf("%lld",&arr[j]);
}
sum=0;
msort(arr,0,n);
// for(j=0;j<n;j++)
// printf("%lld ",arr[j]);
printf("%lld\n",sum);
}
return 0;
}
Here i have written a code which produces next 8 numbers from sequence.
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
I want to know how can i extract each byte/number of the array and return each number/byte ??Please help me out.
EDIT:Here's my code.Basically i want to read a file and compare the contents to check if the data read matches with generated sequential data.Here the buffer contains same data as temp_data is producing(ie 10 numbers like 0x07060504030201 next 0f0e0d0c0b0a0908 etc).I want to comapre buffer's data and the function's data.Can anyone suggest me how can i do.I am stuck.Any changes are appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<inttypes.h>
int main(void){
FILE *fp;
char *buffer,c;
size_t filesize,buffer_size;
int i;
unsigned long long int expected_data=1976943448883713;
fp=fopen("seqdata.c","r");
if(fp==NULL){
fputs("Error\n",stderr);
exit(1);
}
fseek(fp,0L,SEEK_END);
filesize=ftell(fp);
printf("Size of seqdata file is:%u \n",filesize);
fseek(fp,0L,SEEK_SET);
buffer=(char*)malloc(sizeof(char)*filesize);
if(buffer == NULL){
fputs("\nMemory error ",stderr);
}
buffer_size=fread(buffer,sizeof(char),filesize,fp);
for(i=0;i<buffer_size;i++){
printf("%c",*(buffer +i));
}
printf("No of elements read from file are:%u \n",buffer_size);
fseek(fp,0L,SEEK_SET);
int current_pos = 0;
while(current_pos < buffer_size){
if(*(buffer +current_pos) != expected_data)
{
fputs("Error\n",stderr);
exit(1);
}
else{
printf("data matching \n");
current_pos++;
expected_data=next_exp_data(expected_data);
}
}
fclose(fp);
free(buffer);
return 0;
}
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
It's machine dependent, but this usually works one of two ways:
union {
unsigned char b [8];
long long i;
} v;
v .i = seq_gen_value;
for (int j = 0; j < 8; ++j)
printf ("%d, ", v .b [j]);
On a little endian machine (x86, vax, etc.) the bytes come out with the least significant first. On a big endian machine, they come out with the most significant first.
By the way, it would be more useful to encode the "magic numbers" so that they can be more easily understood what they mean. For example, instead of 1976943448883713, write it as 0x7060504030201.
I think that your function do something like
return 1976943448883713 + 8 * 2260630401189896
And I think your question is not clear enough, like what array you want to return each its number? If you want to return array temp_data, it very easy. You can do that by
int next_exp_data(unsigned long long int expected_data, unsigned long long int temp_data[])
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
Call this function with the second params is a array int with size 10.
And another thing, I don't think that this function need the 1st param, because it's not be used within the function, so you can remove that from functions params list
int next_exp_data( unsigned long long int temp_data[])
{
int i=0;
unsigned long long int expected_data;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return expected_data; //dont use (expected_data), it will make things slower.
}
Comparing numbers in C is done using ==, !=, <= , >= , <, or >.
I didn't read your code as it's horrible formatted and doesn't seem relevant to your question as posed in the title.