Whats the difference between this 2 flowing code with same objective - c++

Question:
Starting with a 1-indexed array of size n filled with all zeroes, you are required to perform the following operation m times:
Each operation contains 3 integers a, b and k. You are required to add k to the value at all the indices from a to b (both inclusive).
Once all operations have been performed, return the maximum value in the array.
Input Format:
The first line contains two space-separated integers n and m, the size of the array and the number of operations respectively.
Each of the next m lines contains three space-separated integers a, b and k, the left index, right index and integer to add respectively.
Constraints:
1 <= n, m <= 10^5
1 <= a <= b <= n
-10^9 <= k <= 10^9
Examples:
Sample Input 1:
10 3
1 5 3
4 8 7
6 9 1
Sample Output 1:
10
Explanation:
Given n = 10 and m = 3
Queries are interpreted as follows:
a b k
1 5 3
4 8 7
6 9 1
Add the values of k between the indices a and b inclusive:
1 2 3 4 5 6 7 8 9 10 (index)
[0,0,0,0,0,0,0,0,0,0] (Initially)
[3,3,3,3,3,0,0,0,0,0] (After Query 1)
[3,3,3,10,10,7,7,7,0,0] (After Query 2)
[3,3,3,10,10,8,8,8,1,0] (After Query 3)
The largest value is 10 after all operations are performed.
Sample Input 2:
5 3
1 2 100
2 5 100
3 4 100
Sample Output:
200
Explanation:
After the first update the list is 100 100 0 0 0.
After the second update list is 100 200 100 100 100.
After the third update list is 100 200 200 200 100.
The maximum value is 200.
This code ran and gave the correct output:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<long long int> arr(n, 0);
for (int i = 0; i < m; i++) {
int start, finish, value;
cin >> start >> finish >> value;
arr[start - 1] += value;
arr[finish] -= value;
}
long long int ans = 0;
long long int current = 0;
for (int value : arr) {
current += value;
if (current > ans) {
ans = current;
}
}
cout << ans;
return 0;
}
but this code is giving me segment fault:
#include <bits/stdc++.h>
using namespace std;
int main(){
long long int n,m;
cin>>n>>m;
long long int x[n] ={0};
for(int i=0;i<m;i++)
{
long long int a,b,k;
cin>>a>>b>>k;
x[a-1] += k;
if(b<n)
x[b] -= k;
}
long long int max=0,current=0;
for(int i=0;i<n;i++)
{
current=x[i]+current;
if(max<current)
max=current;
}
cout<<max<< endl;
return 0;
}

Well the problem in your code is in the line x[b] -= k;
Since b is 1-indexed, this means that b can be upto n but your array of size n has indices from 0 to n-1 and if there is a query where b = n, then you get segmentation fault.
You can correct this by placing an if condition just before this line like this:
if (b < n)
Also, in the first code, you should have encountered the same problem but somehow your compiler overlooked the indexing problem in vector.

Related

How to make my code about 'arithmetic substrings' work quicker

I have some problems with code for my classes. Even though it works correctly, I run out of time for half of the examples.
Here's the task (I really did my best trying to translate it):
You have a permutation of numbers 1,2,...,n for some n. All consecutive numbers of permutations together create sequence a1, a2, an. Your task is to count, how many arithmetic substrings of a sequence of length 3 exist.
Input:
In first line there is a number n (1 <= n <= 200 000). In the second line there is n numbers a1, a2...an representing our permutation.
Output:
The program needs to print out amount of arithmetic substrings of length 3 for permutations from entry. You can assume that the result won't be bigger than 1 000 000.
Is there any way to make it work faster? Thanks for help!
#include <iostream>
using namespace std;
int main()
{
int input_length;
cin >> input_length;
int correct_sequences = 0;
bool* whether_itroduced = new bool[input_length + 1]{0}; // true - if number was already introduced and false otherwise.
for (int i = 0; i < input_length; i++)
{
int a;
cin >> a;
whether_itroduced[a] = true;
int range = min(input_length - a, a - 1); // max or min number that may be in the subsequence e.g. if introduced number a = 3, and all numbers are six, max range is 2 (3 - 2 = 1 and 3 + 2 = 5, so the longest possible subsequence is 1, 3, 5)
for (int r = range * -1; r <= range; r++) // r - there is a formula used to count arithmetic sequences -> an-1 = a1-r, an = a1, an+1 = a1+r, I have no idea how to explain it
{
if (r == 0) continue; // r cannot be 0
if (whether_itroduced[a - r] && !whether_itroduced[a + r])
correct_sequences++;
}
}
cout << correct_sequences;
}
example
input:
5
1 5 4 2 3
output:
2
// 1,2,3 and 5,4,3

Find how much xtreme distance two people walk together

Amir and Bond are walking on a street. Initially, both are at the position X=0 and they start walking in the direction of increasing X. After N seconds, they stop. Let's denote Amir's speed and Bond's speed during the i-th of these seconds by Ai and Bi respectively.
Sometimes, Aman and Bond walk together, i.e. with the same speed side by side. Let's define the xtreme distance as the total distance they walk this way. Find this xtreme distance.
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
The second line contains N space-separated integers A1,A2,…,AN.
The third line contains N space-separated integers B1,B2,…,BN.
Output
For each test case, print a single line containing one integer ― the total weird distance. It can be proved that this distance is an integer.
Constraints
1≤T≤20
1≤N≤10e5
1≤Ai≤10e5 for each valid i
1≤Bi≤10e5 for each valid i
the sum of N over all test cases does not exceed 10e6
Code
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
long long int N;
long long int i, w = 0;
cin >> N;
int * A = new int [N+1];
int * X = new int [N+1];
int * B = new int [N+1];
int * Y = new int [N+1];
Y[0] = 0;
X[0] = 0;
for(i=1;i<=N;i++)
{
cin >> A[i];
X[i] = X[i-1] + A[i];
}
for(i=1;i<=N;i++)
{
cin >> B[i];
Y[i] = Y[i-1] + B[i];
}
for(i=1;i<=N;i++)
{
if((X[i]-X[i-1]) == (Y[i]-Y[i-1]))
w += (Y[i] - Y[i-1]);
}
cout << w << endl;
delete [] A;
delete [] B;
delete [] X;
delete [] Y;
}
return 0;
}
Example Input
3
4
1 3 3 4
1 2 4 4
2
2 3
3 2
2
3 3
3 3
Example Output
5
0
6
Error
I am not able to figure out the error (may be there is error in constraints)

Sequence of n numbers - compute all possible k-subsequence of "lucky" numbers

I have a problem with one task, so if you could help me a little bit.
Numbers are "lucky" or "unlucky". Number is "lucky" just if every
digit 7
or every digit is 4. So "lucky" numbers are for example 4, 44, 7, 77.
"Unlucky" are the others numbers.
You will get sequence of n-elements and number K. Your task is to
compute number of all possible k-elements subsequence, which fulfill a one
condition. The condition is that in the subsequence mustn't be two same "lucky"
numbers. So for example there mustn't 77 and 77...
Output number of all possible k-elements subsequence mod 10^9+7
0 < N,K < 10^5
Few examples:
Input:
5 2
7 7 3 7 77
Output:
7
Input:
5 3
3 7 77 7 77
Output:
4
Input:
34 17
14 14 14 ... 14 14 14
Output:
333606206
I have code which seems to work, but it is too slow when I try to compute binomial coefficient. I'm using map. In string I store number in string format. In second - int - part of the map is number which represents how many times was that number(in the first map parameter) used. So now I have stored every "unlucky" numbers stored together. Also every same "lucky" number is together. When I have it stored like this, I just compute all multiplications. For example:
Input
5 2
3 7 7 77 7
Are stored like this: map["other"] = 1 map["7"] = 3 map["77"] = 1
Because k = 2 --> result is: 1*3 + 1*1 + 1*3 = 7.
I think problem is with computing binomial coefficient. For the third example it needs to compute (34 choose 17) and it is computing very long time.I've found this article and also this , but I don't understand how they are solving this problem.
My code:
#include<iostream>
#include<string>
#include<map>
#include <algorithm>
#include <vector>
using namespace std;
int binomialCoeff(int n, int k)
{
// Base Cases
if (k == 0 || k == n)
return 1;
// Recur
return binomialCoeff(n - 1, k - 1) + binomialCoeff(n - 1, k);
}
int main()
{
int n, k;
cin >> n >> k;
map<string, int> mapa; // create map, string is a number, int represents number of used string-stored numbers ---> so if 7 was used two times, in the map it will be stored like this mapa["7"] == 2 and so on)
for (int i = 0; i < n; i++) // I will load number as string, if this number is "lucky" - digist are all 7 or all 4
{ // every "unlucky" numbers are together, as well as all same "lucky" numbers ---> so 77 and 77 will be stored in one element....
string number;
cin >> number;
char digit = number[0];
bool lucky = false;
if (digit == '7' || digit == '4')
lucky = true;
for (int j = 1; j < number.length(); j++) {
if (digit != '7' && digit != '4')
break;
if (number[j] != digit) {
lucky = false;
break;
}
}
if (lucky)
mapa[number]++;
else
mapa["other"]++;
}
vector<bool> v(mapa.size());
bool lack = k > mapa.size(); //lack of elements in map --> it is when mapa.size() < k; i. e. number of elements in array can't make k-element subsequence.
int rest = lack ? k - mapa.size() + 1 : 1; // how many elements from "unlucky" numbers I must choose, so it makes base for binomial coefficient (n choose rest)
if (lack) //if lack is true, different size of vector
fill(v.begin() + mapa.size(), v.end(), true);
else
fill(v.begin() + k, v.end(), true);
int *array = new int[mapa.size()]; //easier to manipulate with array for me
int sum = 0;
int product = 1;
int index = 0;
for (map<string, int> ::iterator pos = mapa.begin(); pos != mapa.end(); ++pos) // create array from map
{
if (lack && pos->first == "other") { //if lack of elements in map, the number in elemets representing "unlucky" numbers will be binomial coefficient (mapa["other] choose rest)
array[index++] = binomialCoeff(mapa["other"], rest);
continue;
}
array[index++] = pos->second;
}
do { // this will create every posible multiplication for k-elements subsequences
product = 1;
for (int i = 0; i < mapa.size(); ++i) {
if (!v[i]) {
product *= array[i];
}
}
sum += product;
} while (next_permutation(v.begin(), v.end()));
if (mapa["other"] >= k && mapa.size() > 1) { // if number of "unlucky" numbers is bigger than k, we need to compute all possible k-elements subsequences just from "unlucky" number, so binomial coefficient (mapa["other] choose k)
sum += binomialCoeff(mapa["other"], k);
}
cout << sum % 1000000007 << endl;
}

SIGSEGV "3n + 1"

100 - The 3n + 1 problem
http://www.spoj.com/problems/PROBTRES/
always i get this >>> runtime error (SIGSEGV) <<<
why plz help !
Background:
Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem you will be analyzing a property of an algorithm whose classification is not known for all possible inputs.
The Problem:
Consider the following algorithm:
1. input n
2. print n
3. if n = 1 then STOP
4. if n is odd then n = 3n + 1
5. else n = n / 2
6. GOTO 2
Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)
Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.
For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.
The Input:
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
You can assume that no operation overflows a 32-bit integer.
The Output:
For each pair of input integers i and j you should output i, j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).
Sample Input:
1 10
100 200
201 210
900 1000
Sample Output:
1 10 20
100 200 125
201 210 89
900 1000 174
#include <iostream>
using namespace std ;
long int a[1000001];
long int F (long int n){
if(a[n]!=0)
return a[n];
else {
if(n%2 !=0)
a[n]=F(n*3+1)+1 ;
else
a[n]=F(n/2)+1 ;
return a[n];
}
}
int main(){
a[1]= 1 ;
long int i , j , MX , MN , x=0 ;
while (cin>>i >> j ){
MX=max(i,j);
MN=min(i,j);
for(;MN<=MX;MN++){
if(x<F(MN))
x=F(MN) ;
}
cout<<i<<" "<<j<<" "<<x<<endl;
x= 0;
}
return 0 ;
}
what is the difference between this and my code ?!!!
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000001
static int result[MAX];
int calculate(unsigned long i);
int main()
{
unsigned long int i = 0;
unsigned long int j = 0;
unsigned long int k = 0;
int max,x,y;
result[1] = result[0] = 1;
while (scanf("%ld",&i)!= EOF)
{
scanf("%ld",&j);
if (i > j)
{
x = i;
y = j;
}
else
{
x = j;
y = i;
}
max = 0;
for (k = y; k <= x; k++)
{
if (result[k] != 0 && result[k] > max)
max = result[k];
else if (calculate(k) > max)
max = result[k];
}
printf("%ld %\ld %d\n",i,j,max);
}
return 0;
}
int calculate(unsigned long i)
{
if (i < MAX && result[i])
return result[i];
if ( i % 2 == 1 )
{
if (i < MAX)
return result[i] = 2+calculate((3*i+1)/2);
else
return 2+calculate((3*i+1)/2);
}
else
{
if( i < MAX)
return result[i] = 1 + calculate(i / 2);
else
return 1 + calculate(i /2 );
}
}
You might check the actual range of values you're getting for n, as it might be stepping outside your array long a[1000001]. Also, you might check your recursion depth. If you recurse too deeply, you'll overflow the stack.
I would consider adding an assert to test n (ie. assert(n < 1000001)), and perhaps a recursion depth variable to check your recursion depth as the first steps to diagnosing and debugging this code. You can find assert in <cassert>.

Optimization or New Algorithm to solve this? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am trying to solve this problem :
Little girl has an array of n elements (the elements of the array are indexed starting from 1).
Also, there are "q" queries, each one is defined by a pair of integers li, ri (1 ≤ li ≤ ri ≤ n). You need to find for each query the sum of elements of the array with indexes from li to ri, inclusive.
The little girl found the problem rather boring. She decided to reorder the array elements before replying to the queries in a way that makes the sum of query replies maximum possible. Your task is to find the value of this maximum sum.
Input:
The first line contains two space-separated integers n (1 ≤ n ≤ 10^5) and q (1 ≤ q ≤ 10^5) — the number of elements in the array and the number of queries, correspondingly.
The next line contains n space-separated integers ai (1 ≤ ai ≤ 10^5) — the array elements.
Each of the following q lines contains two space-separated integers li and ri (1 ≤ li ≤ ri ≤ n) — the i-th query.
Output:
In a single line print a single integer — the maximum sum of query replies after the array elements are reordered.
Sample testcases:
input:
3 3
5 3 2
1 2
2 3
1 3
output
25
input
5 3
5 2 4 1 3
1 5
2 3
2 3
output
33
I have knowledge of Segment tree so i applied Lazy propagation approach through segment tree.
My Effort code :
#include <iostream>
#include <string>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <list>
#include <cmath>
#include <stack>
using namespace std;
#define scan(x) scanf("%d",&x)
#define print(x) printf("%d ",x)
#define println(x) printf("%d\n",x)
#define For(i,a,j,k) for (i = a; i < j; i+= k)
#define For_back(i,a,j,k) for (i = j; i >= a; i-= k)
#define SET(a,x) memset(a,x,sizeof(a))
#define mod 1000000007
#define inf 0x7fffffff
#define Max 2000000
typedef pair<int,int> pii;
typedef pair<pii,int> piii;
long long int tree[3*Max];
long long int lazy[3*Max];
void update(int node,int a,int b,int i,int j,long long int value)
{
if (lazy[node]!= 0)
{
tree[node] += lazy[node];
if (a != b)
{
lazy[2*node] += lazy[node];
lazy[2*node+1] += lazy[node];
}
lazy[node] = 0;
}
if (a > b || a > j || b < i)
return;
if (a >= i && b <= j)
{
tree[node] += value;
if (a != b)
{
lazy[2*node] += value;
lazy[2*node+1] += value;
}
return;
}
int mid = (a+b)/2;
update(2*node,a,mid,i,j,value);
update(2*node+1,mid+1,b,i,j,value);
tree[node] = (tree[2*node]+tree[2*node+1]);
}
long long int query(int node,int a,int b,int i,int j)
{
if (a> b || a > j || b < i) return 0;
if (lazy[node] != 0)
{
tree[node] += lazy[node];
if (a != b)
{
lazy[2*node] += lazy[node];
lazy[2*node+1] += lazy[node];
}
lazy[node] = 0;
}
if (a >= i && b <= j)
return tree[node];
int mid = (a+b)/2;
long long int q1 = query(2*node,a,mid,i,j);
long long int q2 = query(2*node+1,mid+1,b,i,j);
return ((q1+q2));
}
int main()
{
SET(lazy,0);
SET(tree,0);
int n,m;
cin >> n >> m;
int i,j;
int arr[n];
For(i,0,n,1)
{
cin >> arr[i];
}
sort(arr,arr+n);
For(i,0,m,1)
{
long long int num1,num2;
cin >> num1 >> num2;
update(1,0,n-1,num1-1,num2-1,1);
}
long long int my[n];
For(i,0,n,1)
{
long long int number = query(1,0,n-1,i,i);
my[i] = number;
}
sort(my,my+n);
long long int sum = 0;
For_back(i,0,n-1,1){
sum += my[i]*arr[i];
}
cout << sum << endl;
return 0;
}
My approach for this was simple just to do as said using segment tree and lastly print the answer.
My question is is there any simpler Algo for this ? or should i optimize my segment tree code ?
Concept:
"You have to fix the biggest element from array to the index that is queried most times and then second biggest element to second most queried element
Here's implementation of my method:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
using namespace std;
int main()
{
LL n,q,l,r,i;
cin>>n>>q;
LL arr[n];
for(i=0;i<n;i++)
cin>>arr[i];
LL freq[n];
memset(freq,0,sizeof freq);
sort(arr,arr+n);
for(i=0;i<q;i++)
{
cin>>l>>r;
freq[l-1]++; // DP method of freq
if(r<n)
freq[r]--;
}
for(i=1;i<n;i++)
freq[i]+=freq[i-1];
sort(freq,freq+n);
LL ans=0;
for(i=n-1;i>=0;i--)
if(freq[i])
ans+=arr[i]*freq[i];
cout<<ans<<endl;
return 0;
}
Yeah you have to sort the array and then sort frequency and then multiply number with frequency and that will result in maximum sum..
Method to keep count:
Don't update each time from li to ri.
instead just increase the count at each starting position and at one more than end position because you have to include till end.
lastly sum all count. in O(n). and you can know how many time each was increased. sort it and sort the given array and multiply number with frequency so obtained and you have you answer.
input: 5 3
array : 5 2 4 1 3
1st query: 1 5
freq update = 1 0 0 0 0
2nd query: 2 3
freq update =1 1 0 -1 0
3rd query: 2 3
freq update= 1 2 0 -2 0
collective freq=1 3 3 1 1
sorted freq= 1 1 1 3 3
sorted array =1 2 3 4 5
ans =33
I think this will work - comments invited
Create an array of dimension n called count and initialize it to 0
Go through the Q array
For each query
- From li to ri increment count by 1 i.e. the count of elements li to ri
Sort the array n
Sort the count array (remember the index)
Pick up the highest of the count and at the corresponding index put the highest element from N
Continue this for all elements
Basically we are ensuring that the highest element occurs the highest number of times (when referred by the query)
This is what I'd do:
Created a (hash)map index->count. Go through all queries and for each index in the range, increment the count (*).
Order the elements in the array by size, decending (called values now).
Extract the counts from your hashmap (the indexes are irrelevant now, because we don't need them again and the array is reordered accordingly) and also order them decending.
Iterate through the ordered array of counts and sum up sum += counts[i] * values[i]
let's say your array is
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
queries are:
q1: 1-3
q2: 2-4
q3: 3-5
the map:
1->1
2->2
3->3
4->2
5->1
the counts sorted:
3,2,2,1
one of the perfect reorderings (irrelevant for the algorithm, because only the sum is required)
6,7,9,8,5,4,3,2,1,0
sum for queries:
(6 + 7 + 9) + (7 + 9 + 8) + (9 + 8 + 5) = 68
with the algorithm:
3 * 9 + 2 * 8 + 2 * 7 + 1 * 6 + 1 * 5 = 68
(*) If you want to speed this up, you can use an array / vector of size n instead of a map and use indexes as keys. If just mentioned the map in my example because it makes the idea more evident