N by N matrix diagonal difference - c++

Hi I have this following code snippet for getting the difference in an N by N array but it does not seem to be giving me the correct answers I got the algorithm by drawing the N by N matrix on paper and working it out, It does not give me any bugs but does not give me the answer I expect to receive, what am I missing out on
//includes here
int main(){
int n;
int diagOne{0};
int diagTwo{0};
cin >> n;
vector< vector<int> > a(n,vector<int>(n));
for(int a_i = 0;a_i < n;a_i++){
for(int a_j = 0;a_j < n;a_j++){
cin >> a[a_i][a_j];
if (a_i==a_i){
diagOne+=a[a_i][a_j];
}
else if(a_i+a_j==n-1) {
diagTwo+=a[a_i][a_j];
}
}
int sum =abs(diagOne -diagTwo);
}
return 0;
}

Your if in the second for is always true a_i==a_i.

In addition to #Milos Radosavljevic's answer, your int sum =abs(diagOne -diagTwo); is overwriting itself every outer loop. To fix this move it outside the outer loop. Here is a live demo of the fixed version of your code.
Note that this calculates the difference between the sum of the main diagonal and the anti diagonal (trace minus anti-trace). If however, you were after the element-wise difference total then you could do this.

Related

Modulo strength , want explanation in the algorithm used to compute the answer

I was trying to solve the problem Modulo strength at hackerearth ,
https://www.hackerearth.com/practice/basic-programming/implementation/basics-of-implementation/practice-problems/golf/modulo-strength-4/ , so basically we have to find all such pairs of no. (say i,j) such that A[i]%k=A[j]%k where k is a no. given in the question , i tried brute force approach and got time limit exceeded at some of the last test cases and in the discussion tab i found a code which is working but i couldn't understand what exactly it does, and the underlying thinking behind the algorithm used.
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int n,k,s=0;
cin>>n>>k;
int a[n];
vector<int>v(k,0); // Specially this part ,what does it store?
for(int i=0;i<n;i++)
{
cin>>a[i];
v[a[i]%k]++;
}
for(int i=0;i<k;i++)
{
s+=v[i]*(v[i]-1);
}
cout<<s;
}
Here is the code, i wanted to understand it so that i can apply this logic over other problems.
There are a few problems with that;
"bits/stdc++.h" is not a standard header
Variable-length arrays, like int a[n], are non-standard and prone to runtime errors (this one is also completely unnecessary)
#define int long long makes the code have undefined behaviour.
Here is a fixed version, with some minor renaming and clarifying comments:
#include <iostream>
#include <vector>
int main() {
long long n, k;
cin >> n >> k;
// There are k groups of friends.
std::vector<int> friends(k);
// Count how many people there are in each group.
for(int i = 0; i < n; i++)
{
int x;
std::cin >> x;
friends[x%k]++;
}
long long sum = 0;
for(int i = 0; i < k; i++)
{
// In a group of N mutual friends, each person has N-1 friends.
sum += friends[i] * (friends[i]-1);
}
std::cout << sum;
}
Let's first go through with the purpose of every variable in the code.
The purpose of n,k,s is explicitly given.
a[n] is for reading the numbers in array.
std::vector<int>v(k,0) stores k sized vector of 0's, and v[i] indicates the number of variables in a[n] for which a[j]%k==i.
In the last loop, the following has done. The number of pairs that can be constructed with n elements is n*(n-1) (basic combinatorics), and if we have v[i] numbers for which the condition is satisfied and a[j]%k==i the number of pairs that can be constructed is v[i]*(v[i]-1). The loop sums up the number of pairs for every remnant i.

Confusing logic of dp

I am trying to solve a dynamic programming question on hackerearth.
Even after trying to simulate the logic using pen and paper, I am unable to comprehend the solution (given in the editorial).
Can someone explain the commented lines? Any help would be greatly appreciated. I have been trying to understand it for 3 days...
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 5e3+5;
bool vis[MAXN];
int ar[MAXN];
int pre[MAXN];
vector<int> v;
int dp[MAXN];
void sieve() {
v.push_back(2);
for(int i=3;i<MAXN;i+=2) if(!vis[i]) {
v.push_back(i);
for(int j=i*i;j<MAXN;j+=2*i) vis[j]=true;
}
}
int main() {
// freopen("TASK.in","r",stdin);
// freopen("TASK.out","w",stdout);
int n;
cin>>n;
assert(n<=5000);
for(int i=1;i<=n;i++) {
scanf("%d",&ar[i]);
assert(ar[i]<=100000);
pre[i]=pre[i-1]+ar[i];
}
sieve();
dp[0]=dp[1]=0;
for(int i=2;i<=n;i++) {
dp[i]=dp[i-1];
for(int j=0;j<(int)v.size() and v[j]<=i;j++) {
int p=i-v[j]-1;//please explain this line
if(p==-1) dp[i]=max(dp[i],pre[i]);
else dp[i]=max(dp[i],dp[p]+pre[i]-pre[p+1]);// please explain this line
}
}
cout<<dp[n]<<endl;
return 0;
}
Here array prestands for prefix sum, vector v contains prime numbers below MAXN. First line you have commented is
int p=i-v[j]-1;
Here v[j] is the jth prime number starting from 2, dp[i] is the best possible score for first i problems. If you solve v[j] number of consecutive problems (from i and going backward) you are left with i - v[j] problems from the beginning. -1 comes from the fact that you cannot solve the (v[j] - 1) th problem from i (backward) (if you do that you will have solved v[j] + 1 consecutive problems which is not prime as v[j] is prime).
Second line you have commented:
dp[i]=max(dp[i],dp[p]+pre[i]-pre[p+1]);
It follows from above since if you solve v[j] problems from i (backward) you get pre[i]-pre[p+1] points and you add that with dp[p] which is best result you already obtained for p. For example if i = 10 and v[j] = 3 you get dp[10] = max (dp[10],dp[6]+pre[10]-pre[7]) which is what you would expect.

How to efficiently find coefficients of a polynomial from its roots? [duplicate]

This question already has answers here:
Sum of multiplication of all combination of m element from an array of n elements
(3 answers)
Closed 7 years ago.
Given are the n roots of a polynomial whose leading coefficient is 1.
How do I efficiently find out the coefficients of this polynomial?
Mathematically,
I know that if the first coefficient is 1, then sum of product roots taken k at a time will be the k+1-th coefficient of the polynomial.
My code is based on this approach.
In other words, how to optimally find the sum of product of numbers from a list taken k at a time.
int main()
{
int n, sum;
cin >> n;
int a[n];
for (int i=0; i<n; i++) cin >> a[i];
//for the second coefficient
sum=0;
for (int i=0; i<n; i++)
{
sum+=a[i];
}
cout << sum << endl;
//for the third coefficient
sum=0;
for (int i=0; i<n; i++)
{
for (int j=i+1; j<n; j++)
{
sum+=a[i]*a[j];
}
}
cout << sum << endl;
}
I have thought of marking the numbers on whether I have taken them into the product or not for the purpose of higher coefficients, but have not written the code for it as it is practically of no use if the degree of polynomial is large.
You need to compute the product of linear factors
(x-z1)·(x-z2)·…·(x-zn)
This can be implemented inductively by repeatedly multiplying a polynomial with a linear factor
(a[0]+a[1]·x+…+a[m-1]·x^(m-1))·(x-zm)
= (-a[0]·zm) + (a[0]-a[1]·zm)·x + … + (a[m-2]-a[m-1]·zm) ·x^(m-1) + a[m-1]·x^m
In place this can be implemented as loop
a[m] = a[m-1]
for k = m-1 downto 1
a[k] = a[k-1] - a[k]*zm
end
a[0] = -a[0]*zm
This gives a total of n²/2 multiplications and a like number of subtractions for the multiplication of all n linear factors.
First of all in C++ a[n] is a static array, so compiler need to know n during compile time, which is not the case here. So the code is "not correct" in C++. I know it will compile in gcc or other compilers, but it is against C++ standard. See C++ declare an array based on a non-constant variable? What you need here is a dynamic array, using new and delete command, or you can use more safe std::vector class from STL.
Now, the main problem here is that you need k nested loops, if you want to calculate k'th coefficients, (I am assuming 1 is 0th coefficient, not 1st, just convention). So, you need to implement variable no. of nested for loops in your code. I am posting the solution of your problem, in which I used a method to implement variable no. of nested for loops. Hope this will solve your problem.
#include <iostream>
#include <cmath>
#include <vector> // include vector class
using namespace std;
double coeff(int,const vector<double>& ); // function declaration to to calculate coefficients
int main()
{
int N = 5; // no. of roots
// dynamic vector containing values of roots
vector<double> Roots(N);
for(int i = 0 ; i<N ; ++i)
Roots[i] = (double)(i+1); // just an example, you can use std::cin
int K = 2; // say you want to know K th coefficient of the polynomial
double K_th_coeff = coeff(K,Roots); // function call
cout<<K_th_coeff<<endl; // print the value
return 0;
}
double coeff(int k,const vector<double>& roots)
{
int size = roots.size(); // total no. of roots
int loop_no = k; // total no. of nested loops
vector<int> loop_counter(loop_no+1); // loop_counter's are the actual iterators through the nested loops
// like i_1, i_2, i_3 etc., loop_counter[loop_no] is needed to maintain the condition of the loops
for(int i=0; i<loop_no+1; ++i)
loop_counter[i]=0; // initialize all iterators to zero
vector<int> MAX(loop_no+1); // MAX value for a loop, like for(int i_1=0; i_1 < MAX[1]; i++)...
for(int i=0 ; i<loop_no ; ++i)
MAX[i] = size - loop_no + i + 1; // calculated from the algorithm
MAX[loop_no]=2; // do'es no matter, just != 1
int p1=0; // required to maintain the condition of the loops
double sum(0); // sum of all products
while(loop_counter[loop_no]==0)
{
// variable nested loops starts here
int counter(0);
// check that i_1 < i_2 < i_3 ....
for(int i = 1 ; i < loop_no; ++i)
{
if(loop_counter[i-1] < loop_counter[i])
++counter;
}
if(counter == loop_no - 1) // true if i_1 < i_2 < i_3 ....
{
double prod(1);
for(int i = 0 ; i < loop_no ; ++i)
prod *= roots[loop_counter[i]]; // taking products
sum += prod; // increament
}
// variable nested loops ends here...
++loop_counter[0];
while(loop_counter[p1]==MAX[p1])
{
loop_counter[p1]=0;
loop_counter[++p1]++;
if(loop_counter[p1]!=MAX[p1])
p1=0;
}
}
return pow(-1.0,k)*sum; // DO NOT FORGET THE NEGATIVE SIGN
}
I have checked the code, and it is working perfectly. If you want to know how to implement variable no.of nested for loops, just visit variable nested for loops and see BugMeNot2013's answer.

Count number of ways for choosing two numbers in efficient algorithm

I solved this problem but I got TLE Time Limit Exceed on online judge
the output of program is right but i think the way can be improved to be more efficient!
the problem :
Given n integer numbers, count the number of ways in which we can choose two elements such
that their absolute difference is less than 32.
In a more formal way, count the number of pairs (i, j) (1 ≤ i < j ≤ n) such that
|V[i] - V[j]| < 32. |X|
is the absolute value of X.
Input
The first line of input contains one integer T, the number of test cases (1 ≤ T ≤ 128).
Each test case begins with an integer n (1 ≤ n ≤ 10,000).
The next line contains n integers (1 ≤ V[i] ≤ 10,000).
Output
For each test case, print the number of pairs on a single line.
my code in c++ :
int main() {
int T,n,i,j,k,count;
int a[10000];
cin>>T;
for(k=0;k<T;k++)
{ count=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
if(i!=j)
{
if(abs(a[i]-a[j])<32)
count++;
}
}
}
cout<<count<<endl;
}
return 0;
}
I need help how can I solve it in more efficient algorithm ?
Despite my previous (silly) answer, there is no need to sort the data at all. Instead you should count the frequencies of the numbers.
Then all you need to do is keep track of the number of viable numbers to pair with, while iterating over the possible values. Sorry no c++ but java should be readable as well:
int solve (int[] numbers) {
int[] frequencies = new int[10001];
for (int i : numbers) frequencies[i]++;
int solution = 0;
int inRange = 0;
for (int i = 0; i < frequencies.length; i++) {
if (i > 32) inRange -= frequencies[i - 32];
solution += frequencies[i] * inRange;
solution += frequencies[i] * (frequencies[i] - 1) / 2;
inRange += frequencies[i];
}
return solution;
}
#include <bits/stdc++.h>
using namespace std;
int a[10010];
int N;
int search (int x){
int low = 0;
int high = N;
while (low < high)
{
int mid = (low+high)/2;
if (a[mid] >= x) high = mid;
else low = mid+1;
}
return low;
}
int main() {
cin >> N;
for (int i=0 ; i<N ; i++) cin >> a[i];
sort(a,a+N);
long long ans = 0;
for (int i=0 ; i<N ; i++)
{
int t = search(a[i]+32);
ans += (t -i - 1);
}
cout << ans << endl;
return 0;
}
You can sort the numbers, and then use a sliding window. Starting with the smallest number, populate a std::deque with the numbers so long as they are no larger than the smallest number + 31. Then in an outer loop for each number, update the sliding window and add the new size of the sliding window to the counter. Update of the sliding window can be performed in an inner loop, by first pop_front every number that is smaller than the current number of the outer loop, then push_back every number that is not larger than the current number of the outer loop + 31.
One faster solution would be to first sort the array, then iterate through the sorted array and for each element only visit the elements to the right of it until the difference exceeds 31.
Sorting can probably be done via count sort (since you have 1 ≤ V[i] ≤ 10,000). So you get linear time for the sorting part. It might not be necessary though (maybe quicksort suffices in order to get all the points).
Also, you can do a trick for the inner loop (the "going to the right of the current element" part). Keep in mind that if S[i+k]-S[i]<32, then S[i+k]-S[i+1]<32, where S is the sorted version of V. With this trick the whole algorithm turns linear.
This can be done constant number of passes over the data, and actually can be done without being affected by the value of the "interval" (in your case, 32).
This is done by populating an array where a[i] = a[i-1] + number_of_times_i_appears_in_the_data - informally, a[i] holds the total number of elements that are smaller/equals to i.
Code (for a single test case):
static int UPPER_LIMIT = 10001;
static int K = 32;
int frequencies[UPPER_LIMIT] = {0}; // O(U)
int n;
std::cin >> n;
for (int i = 0; i < n; i++) { // O(n)
int x;
std::cin >> x;
frequencies[x] += 1;
}
for (int i = 1; i < UPPER_LIMIT; i++) { // O(U)
frequencies[i] += frequencies[i-1];
}
int count = 0;
for (int i = 1; i < UPPER_LIMIT; i++) { // O(U)
int low_idx = std::max(i-32, 0);
int number_of_elements_with_value_i = frequencies[i] - frequencies[i-1];
if (number_of_elements_with_value_i == 0) continue;
int number_of_elements_with_value_K_close_to_i =
(frequencies[i-1] - frequencies[low_idx]);
std::cout << "i: " << i << " number_of_elements_with_value_i: " << number_of_elements_with_value_i << " number_of_elements_with_value_K_close_to_i: " << number_of_elements_with_value_K_close_to_i << std::endl;
count += number_of_elements_with_value_i * number_of_elements_with_value_K_close_to_i;
// Finally, add "duplicates" of i, this is basically sum of arithmetic
// progression with d=1, a0=0, n=number_of_elements_with_value_i
count += number_of_elements_with_value_i * (number_of_elements_with_value_i-1) /2;
}
std::cout << count;
Working full example on IDEone.
You can sort and then use break to end loop when ever the range goes out.
int main()
{
int t;
cin>>t;
while(t--){
int n,c=0;
cin>>n;
int ar[n];
for(int i=0;i<n;i++)
cin>>ar[i];
sort(ar,ar+n);
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(ar[j]-ar[i] < 32)
c++;
else
break;
}
}
cout<<c<<endl;
}
}
Or, you can use a hash array for the range and mark occurrence of each element and then loop around and check for each element i.e. if x = 32 - y is present or not.
A good approach here is to split the numbers into separate buckets:
constexpr int limit = 10000;
constexpr int diff = 32;
constexpr int bucket_num = (limit/diff)+1;
std::array<std::vector<int>,bucket_num> buckets;
cin>>n;
int number;
for(i=0;i<n;i++)
{
cin >> number;
buckets[number/diff].push_back(number%diff);
}
Obviously the numbers that are in the same bucket are close enough to each other to fit the requirement, so we can just count all the pairs:
int result = std::accumulate(buckets.begin(), buckets.end(), 0,
[](int s, vector<int>& v){ return s + (v.size()*(v.size()-1))/2; });
The numbers that are in non-adjacent buckets cannot form any acceptable pairs, so we can just ignore them.
This leaves the last corner case - adjacent buckets - which can be solved in many ways:
for(int i=0;i<bucket_num-1;i++)
if(buckets[i].size() && buckets[i+1].size())
result += adjacent_buckets(buckets[i], buckets[i+1]);
Personally I like the "occurrence frequency" approach on the one bucket scale, but there may be better options:
int adjacent_buckets(const vector<int>& bucket1, const vector<int>& bucket2)
{
std::array<int,diff> pairs{};
for(int number : bucket1)
{
for(int i=0;i<number;i++)
pairs[i]++;
}
return std::accumulate(bucket2.begin(), bucket2.end(), 0,
[&pairs](int s, int n){ return s + pairs[n]; });
}
This function first builds an array of "numbers from lower bucket that are close enough to i", and then sums the values from that array corresponding to the upper bucket numbers.
In general this approach has O(N) complexity, in the best case it will require pretty much only one pass, and overall should be fast enough.
Working Ideone example
This solution can be considered O(N) to process N input numbers and constant in time to process the input:
#include <iostream>
using namespace std;
void solve()
{
int a[10001] = {0}, N, n, X32 = 0, ret = 0;
cin >> N;
for (int i=0; i<N; ++i)
{
cin >> n;
a[n]++;
}
for (int i=0; i<10001; ++i)
{
if (i >= 32)
X32 -= a[i-32];
if (a[i])
{
ret += a[i] * X32;
ret += a[i] * (a[i]-1)/2;
X32 += a[i];
}
}
cout << ret << endl;
}
int main()
{
int T;
cin >> T;
for (int i=0 ; i<T ; i++)
solve();
}
run this code on ideone
Solution explanation: a[i] represents how many times i was in the input series.
Then you go over entire array and X32 keeps track of number of elements that's withing range from i. The only tricky part really is to calculate properly when some i is repeated multiple times: a[i] * (a[i]-1)/2. That's it.
You should start by sorting the input.
Then if your inner loop detects the distance grows above 32, you can break from it.
Thanks for everyone efforts and time to solve this problem.
I appreciated all Attempts to solve it.
After testing the answers on online judge I found the right and most efficient solution algorithm is Stef's Answer and AbdullahAhmedAbdelmonem's answer also pavel solution is right but it's exactly same as Stef solution in different language C++.
Stef's code got time execution 358 ms in codeforces online judge and accepted.
also AbdullahAhmedAbdelmonem's code got time execution 421 ms in codeforces online judge and accepted.
if they put detailed explanation to there algorithm the bounty will be to one of them.
you can try your solution and submit it to codeforces online judge at this link after choosing problem E. Time Limit Exceeded?
also I found a great algorithm solution and more understandable using frequency array and it's complexity O(n).
in this algorithm you only need to take specific range for each inserted element to the array which is:
begin = element - 32
end = element + 32
and then count number of pair in this range for each inserted element in the frequency array :
int main() {
int T,n,i,j,k,b,e,count;
int v[10000];
int freq[10001];
cin>>T;
for(k=0;k<T;k++)
{
count=0;
cin>>n;
for(i=1;i<=10000;i++)
{
freq[i]=0;
}
for(i=0;i<n;i++)
{
cin>>v[i];
}
for(i=0;i<n;i++)
{
count=count+freq[v[i]];
b=v[i]-31;
e=v[i]+31;
if(b<=0)
b=1;
if(e>10000)
e=10000;
for(j=b;j<=e;j++)
{
freq[j]++;
}
}
cout<<count<<endl;
}
return 0;
}
finally i think the best approach to solve this kind of problems to use frequency array and count number of pairs in specific range because it's time complexity is O(n).

Trouble sieving primes from a large range

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int main() {
int t,m,n;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
int rootn=sqrt(double(n));
bool p[10000]; //finding prime numbers from 1 to square_root(n)
for(int j=0;j<=rootn;j++)
p[j]=true;
p[0]=false;
p[1]=false;
int i=rootn;
while(i--)
{
if(p[i]==true)
{
int c=i;
do
{
c=c+i;
p[c]=false;
}while(c+p[i]<=rootn);
}
};
i=0;
bool rangep[10000]; //used for finding prime numbers between m and n by eliminating multiple of primes in between 1 and squareroot(n)
for(int j=0;j<=n-m+1;j++)
rangep[j]=true;
i=rootn;
do
{
if(p[i]==true)
{
for(int j=m;j<=n;j++)
{
if(j%i==0&&j!=i)
rangep[j-m]=false;
}
}
}while(i--);
i=n-m;
do
{
if(rangep[i]==true)
printf("%d\n",i+m);
}while(i--);
printf("\n");
}
return 0;
system("PAUSE");
}
Hello I'm trying to use the sieve of Eratosthenes to find prime numbers in a range between m to n where m>=1 and n<=100000000. When I give input of 1 to 10000, the result is correct. But for a wider range, the stack is overflowed even if I increase the array sizes.
               
A simple and more readable implementation
void Sieve(int n) {
int sqrtn = (int)sqrt((double)n);
std::vector<bool> sieve(n + 1, false);
for (int m = 2; m <= sqrtn; ++m) {
if (!sieve[m]) {
cout << m << " ";
for (int k = m * m; k <= n; k += m)
sieve[k] = true;
}
}
for (int m = sqrtn; m <= n; ++m)
if (!sieve[m])
cout << m << " ";
}
Reason of getting error
You are declaring an enormous array as a local variable. That's why when the stack frame of main is pushed it needs so much memory that stack overflow exception is generated. Visual studio is tricky enough to analyze the code for projected run-time stack usage and generate exception when needed.
Use this compact implementation. Moreover you can have bs declared in the function if you want. Don't make implementations complex.
Implementation
typedef long long ll;
typedef vector<int> vi;
vi primes;
bitset<100000000> bs;
void sieve(ll upperbound) {
_sieve_size = upperbound + 1;
bs.set();
bs[0] = bs[1] = 0;
for (ll i = 2; i <= _sieve_size; i++)
if (bs[i]) { //if not marked
for (ll j = i * i; j <= _sieve_size; j += i) //check all the multiples
bs[j] = 0; // they are surely not prime :-)
primes.push_back((int)i); // this is prime
} }
call from main() sieve(10000);. You have primes list in vector primes.
Note: As mentioned in comment--stackoverflow is quite unexpected error here. You are implementing sieve but it will be more efficient if you use bistet instead of bool.
Few things like if n=10^8 then sqrt(n)=10^4. And your bool array is p[10000]. So there is a chance of accessing array out of bound.
I agree with the other answers,
saying that you should basically just start over. 
Do you even care why your code doesn’t work?  (You didn’t actually ask.)
I’m not sure that the problem in your code
has been identified accurately yet. 
First of all, I’ll add this comment to help set the context:
// For any int aardvark;
// p[aardvark] = false means that aardvark is composite (i.e., not prime).
// p[aardvark] = true means that aardvark might be prime, or maybe we just don’t know yet.
Now let me draw your attention to this code:
int i=rootn;
while(i--)
{
if(p[i]==true)
{
int c=i;
do
{
c=c+i;
p[c]=false;
}while(c+p[i]<=rootn);
}
};
You say that n≤100000000 (although your code doesn’t check that), so,
presumably, rootn≤10000, which is the dimensionality (size) of p[]. 
The above code is saying that, for every integer i
(no matter whether it’s prime or composite),
2×i, 3×i, 4×i, etc., are, by definition, composite. 
So, for c equal to 2×i, 3×i, 4×i, …,
we set p[c]=false because we know that c is composite.
But look closely at the code. 
It sets c=c+i and says p[c]=false
before checking whether c is still in range
to be a valid index into p[]. 
Now, if n≤25000000, then rootn≤5000. 
If i≤ rootn, then i≤5000, and, as long as c≤5000, then c+i≤10000. 
But, if n>25000000, then rootn>5000,†
and the sequence i=rootn;, c=i;, c=c+i;
can set c to a value greater than 10000. 
And then you use that value to index into p[]. 
That’s probably where the stack overflow occurs.
Oh, BTW; you don’t need to say if(p[i]==true); if(p[i]) is good enough.
To add insult to injury, there’s a second error in the same block:
while(c+p[i]<=rootn). 
c and i are ints,
and p is an array of bools, so p[i] is a bool —
and yet you are adding c + p[i]. 
We know from the if that p[i] is true,
which is numerically equal to 1 —
so your loop termination condition is while (c+1<=rootn);
i.e., while c≤rootn-1. 
I think you meant to say while(c+i<=rootn).
Oh, also, why do you have executable code
immediately after an unconditional return statement? 
The system("PAUSE"); statement cannot possibly be reached.
(I’m not saying that those are the only errors;
they are just what jumped out at me.)
______________
† OK, splitting hairs, n has to be ≥ 25010001
(i.e., 50012) before rootn>5000.