c++ loop for lowest common multiple - for-loop

I have some problems with this task: you read prom file "perechi.in" a number n and you have to write in a file "perechi.out" how many pairs of numbers have the LCM equal with n. I wrote that code but it crashes and i cannot find out the issue
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int a, b, c, ca, cb, i = 0, n;
ifstream f("perechi.in");
ofstream g("perechi.out");
f >> n;
for (a = 1; a<n; a++){
for (b = 1; b<n; b++){
ca = a;
cb = b;
c = ca%cb;
while (c>0){
ca = cb;
cb = c;
c = ca%cb;
}
if (ca*cb / c == n){
i++;
}
}
}
g << i << "\n";
f.close();
g.close();
return 0;
}

You have two logical mistakes in your code
1) while
2) if (ca*cb / c == n){
Try the following code
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int a, b, c, ca, cb, i = 0, n;
ifstream f("perechi.in");
ofstream g("perechi.out");
f >> n;
for (a = 1; a<=n; a++){
for (b = 1; b<=n; b++){
ca = a;
cb = b;
c = ca%cb;
if (c>0){
ca = cb;
cb = c;
c = ca%cb;
}
if (ca*cb == n){
i++;
}
}
}
g << i << "\n";
f.close();
g.close();
return 0;
}

Related

CSES Dynamic Range Minimum Queries

https://cses.fi/problemset/task/1649
I'm solving this problem using Segment Trees and the solution I've written is
#include <bits/stdc++.h>
#define MAX 1000000001
using namespace std;
int n;
vector<int> tree;
int sum(int a, int b)
{
a += n;
b += n;
int s = INT_MAX;
while(a <= b) {
if (a % 2 == 1) s = min(s, tree[a++]);
if (b % 2 == 0) s = min(s, tree[b--]);
a>>=1;
b>>=1;
}
return s;
}
void update(int k, int change)
{
k += n;
tree[k] = change;
for(int i = k>>1; i >= 1; i>>=1) {
tree[i] = min(tree[2*i], tree[2*i+1]);
}
return;
}
int main()
{
int q;
cin >> n >> q;
n = pow(2, ceil(log2(n)));
tree.resize(2*n, INT_MAX);
for(int i = 0; i < n; i++) {
cin >> tree[i+n];
}
for(int i = n-1; i >= 1; i--) {
tree[i] = min(tree[2*i], tree[2*i+1]);
}
int type, a, b;
for(int i = 0; i < q; i++) {
cin >> type >> a >> b;
if (type == 1) {
update(a-1, b);
} else {
cout << sum(a-1, b-1) << endl;
}
}
return 0;
}
It works with first test case, but not with the second one. I've looked at other solutions online and they all look similar to mine. Please, help me spot the mistake.

Mapping a large number to a unique number using MOD operation

Let the Roots of a first degree polynomial( Q(x) ) be x0 = -b/a. Since the range of the variable a and b is large, x0 can be large as well for it to be stored in a variable(x0).
so, it is converted to some unique number using some operation with mod
int x0 = mul(mod - b, rev(a));
problem link: hackerank problem
Can someone please explain how this line of code works and the math behind this operation?
the whole code-
#include <bits/stdc++.h>
using namespace std;
#define forn(i,n) for (int i = 0; i < int(n); ++i)
typedef long long ll;
const int inf = int(1e9) + int(1e5);
const ll infl = ll(2e18) + ll(1e10);
const int mod = 1e9 + 7;
int udd(int &a, int b) {
a += b;
if (a >= mod)
a -= mod;
return a;
}
int add(int a, int b) {
return udd(a, b);
}
int mul(ll a, ll b) {
return a * b % mod;
}
//============didnt understand this step
int bin(int a, int d) {
int b = 1;
while (d) {
if (d & 1)
b = mul(b, a);
d >>= 1;
a = mul(a, a);
}
return b;
}
int rev(int a) {
assert(a != 0);
return bin(a, mod - 2);
}
const int maxn = 100100;
int px[maxn];
int c[maxn];
struct Fenwick {
int a[maxn];
int t[maxn];
void set(int pos, int val) {
int delta = add(val, mod - a[pos]);
a[pos] = val;
delta = mul(delta, px[pos]);
for (int i = pos; i < maxn; i |= i + 1) {
udd(t[i], delta);
}
}
int get(int r) {
int res = 0;
for (int i = r - 1; i >= 0; i = (i & (i + 1)) - 1)
udd(res, t[i]);
return res;
}
int get(int l, int r) {
return add(get(r), mod - get(l));
}
} fw;
int main() {
#ifdef LOCAL
assert(freopen("test.in", "r", stdin));
#endif
int n, a, b, q;
cin >> n >> a >> b >> q;
//========what does this line do?
int x0 = mul(mod - b, rev(a));
px[0] = 1;
for (int i = 1; i < n; ++i)
px[i] = mul(px[i - 1], x0);
forn (i, n) {
cin >> c[i];
fw.set(i, c[i]);
}
forn (i, q) {
int t, a, b;
cin >> t >> a >> b;
if (t == 1) {
fw.set(a, b);
} else {
++b;
int s = fw.get(a, b);
if (x0 == 0)
s = fw.a[a];
cout << (s == 0 ? "Yes" : "No") << '\n';
}
}
}
bin is the halving-and-squaring implementation for the (in this case modular) power function a^d % mod, so that the modular inverse in rev can be computed via the little theorem of Fermat.

Parallel Matrix Multiplication in C++

I am trying to implement Parallel Multi-threaded Matrix multiplication in C++. The method i follow involves dividing Arrays into 4 sub-arrays and carry out parallel Multiplication using 4 threads on these 4 sub arrays.
I have written a C++ code but it is throwing error and terminates explicitly. Error :
"terminate called after throwing an instance of std::system_error
what():invalid Argument"
Here is my complete code. I am relatively new to C++ and multi-threading.
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <algorithm>
#include <string>
#define N 4
using namespace std;
mutex mu;
void stage_1_multiply(int *a,int *b,int *d){
int *xij;
int *yij;
int *zij;
int COLS = N,ROWS = N;
cout<< " thread "<< this_thread::get_id() << " "<<endl;
for(int i = 0;i<(N/2);++i){
for(int j = 0;j < (N/2); j++){
for(int k = 0; k<(N/2);k++){
mu.lock();
xij = a + ((COLS * i) + k);
yij = b + ((COLS * k) + j);
zij = d + ((COLS * i) + j);
*zij += ( (*xij) * (*yij) );
mu.unlock();
}
}
}
}
int main(){
int A[4][4],B[4][4],C[4][4],D_1[4][4],D_2[4][4];
for(int i = 0;i<4;i++){
for(int j = 0;j<4;j++){
A[i][j] = i + 1;
B[i][j] = i + 1;
C[i][j] = 0;
D_1[i][j] = 0;
D_2[i][j] = 0;
}
}
for(int i = 0;i<4;i++){
for(int j = 0;j< 4;j++){
cout << A[i][j] << " ";
}
cout << endl;
}
for(int i = 0;i<4;i++){
for(int j = 0;j< 4;j++){
cout << B[i][j] << " ";
}
cout << endl;
}
vector< thread> threads(8);
int th = 0;
threads[th++] = thread(stage_1_multiply,&A[0][0],&B[0][0],&D_1[0][0]);
threads[th++] = thread(stage_1_multiply,&A[0][2],&B[2][0],&D_2[0][0]);
threads[th++] = thread(stage_1_multiply,&A[2][0],&B[0][2],&D_1[2][2]);
threads[th++] = thread(stage_1_multiply,&A[2][2],&B[2][2],&D_2[2][2]);
for( auto& t : threads){
t.join();
}
threads[th++] = thread(stage_1_multiply,&A[0][0],&B[0][2],&D_1[0][2]);
threads[th++] = thread(stage_1_multiply,&A[0][2],&B[2][2],&D_2[0][2]);
threads[th++] = thread(stage_1_multiply,&A[2][0],&B[0][0],&D_1[2][0]);
threads[th++] = thread(stage_1_multiply,&A[2][2],&B[2][0],&D_2[2][0]);
for( auto& t : threads){
t.join();
}
// code to add The Matrices D_1 and D_2 goes here.
for(int i = 0;i<4;i++){
for(int j = 0;j< 4;j++){
cout << D_1[i][j] << " ";
}
cout << endl;
}
cout << " Main Close "<<endl;
return 0;
}
What am doing wrong? is it anything related to parallel access of shared memory? If so how can i correct it?
PS: This is a homework Assignment.

Unable to find a wrong answer testcase for spoj MMINPAID

Problem link : http://www.spoj.com/problems/MMINPAID/
Getting WA on submitting.
I have used bfs to reach Nth node and calculating minimum cost for nodes in a path using bitmask. However after running on a huge number of testcases and comparing with an accepted solution, not able to find a failure testcase.
Code:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int MAXN = 15, INF = 1 << 29;
struct node {
int c, p, r;
};
struct node data[MAXN][MAXN];
vector<int> g[MAXN];
int N, M, dist[MAXN][1 << 11];
int bfs() {
for (int i = 0; i < MAXN; i++)
for (int k = 0; k < (1 << 11); k++)
dist[i][k] = INF;
queue< pair< pair <int, int> , int > > q;
int v = 1, path = (1 << 1), cost = 0;
dist[v][path] = 0;
q.push(make_pair(make_pair(v, path), cost));
while (!q.empty()) {
int curv = q.front().first.first;
int curpath = q.front().first.second;
int curcost = q.front().second;
q.pop();
for (int i = 0; i < g[curv].size(); i++) {
int nv = g[curv][i];
int d1 = curcost + data[curv][nv].r;
int d2 = INF;
if (curpath & (1 << data[curv][nv].c)) {
d2 = curcost + data[curv][nv].p;
}
int d3 = min(d1, d2);
int npath = curpath | (1 << nv);
if (d3 < dist[nv][npath]) {
dist[nv][npath] = d3;
q.push(make_pair(make_pair(nv, npath), d3));
}
}
}
int res = INF;
for (int i = 0; i < (1 << 11); i++) {
res = min(res, dist[N][i]);
}
return res;
}
int main() {
scanf("%d %d", &N, &M);
for (int i = 0; i < M; i++) {
int a, b, c, p, r;
scanf("%d %d %d %d %d", &a, &b, &c, &p, &r);
g[a].push_back(b);
data[a][b] = (struct node) {c, p, r};
}
int ret = bfs();
if (ret == INF) printf("impossible\n");
else printf("%d\n", ret);
return 0;
}
I think the problem might be that your data[a][b] structure assumes there is at most a single road from a to b.
However, the problem states:
There may be more than one road connecting one city with another.

(ACM) How to use segment tree to count how many elements in [a,b] is smaller than a given constant?

I am quite new to segment tree and would like to make myself busy by doing some more exercise on segment tree.
The problem's actually more ACM like and have following conditions:
There are n numbers and m operations, n,m<=10,000, each operation can be one of the following:
1. Update an interval by minus a number x, x can be different each time
2. Query an interval to find how many numbers in the interval is <= 0
Building the segment tree and updating here is obviously can be done in O(nlog n) / O(log n)
But I cannot figure out how to make a query in O(log n), can anyone give me some suggestions / hints?
Any suggestions would be helpful! Thanks!
TL;DR:
Given n numbers, and 2 type operations:
add x to all elements in [a,b], x can be different each time
Query number of elements in [a,b] is < C, C is given constant
How to make operation 1 & 2 both can be done in O(log n)?
Nice Problem:)
I think for a while but still can't work out this problem with segment tree, but I've tried using "Bucket Method" to solve this problem.
We can divide the initial n numbers into B buckets, sort the number in each buckets and maintain the total add val in each bucket. Then for each query:
"Add" update interval [a, b] with c
we only need to rebuild at most two buckets and add c to (b - a) / BUCKET_SIZE buckets
"Query" query interval [a, b] <= c
we only need to scan at most two buckets with each value one by one and quick go through (b-a) / BUCKET_SIZE buckets with binary search quickly
It should be run in O( N/BUCKET_SIZE * log(BUCKET_SIZE, 2)) for each query, which is smaller than bruteforce method( O(N)). Though it's bigger than O(logN), it may be sufficient in most cases.
Here are the test code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <ctime>
#include <cassert>
using namespace std;
struct Query {
//A a b c add c in [a, b] of arr
//Q a b c Query number of i in [a, b] which arr[i] <= c
char ty;
int a, b, c;
Query(char _ty, int _a, int _b, int _c):ty(_ty), a(_a), b(_b), c(_c){}
};
int n, m;
vector<int> arr;
vector<Query> queries;
vector<int> bruteforce() {
vector<int> ret;
vector<int> numbers = arr;
for (int i = 0; i < m; i++) {
Query q = queries[i];
if (q.ty == 'A') {
for (int i = q.a; i <= q.b; i++) {
numbers[i] += q.c;
}
ret.push_back(-1);
} else {
int tmp = 0;
for(int i = q.a; i <= q.b; i++) {
tmp += numbers[i] <= q.c;
}
ret.push_back(tmp);
}
}
return ret;
}
struct Bucket {
vector<int> numbers;
vector<int> numbers_sorted;
int add;
Bucket() {
add = 0;
numbers_sorted.clear();
numbers.clear();
}
int query(int pos) {
return numbers[pos] + add;
}
void add_pos(int pos, int val) {
numbers[pos] += val;
}
void build() {
numbers_sorted = numbers;
sort(numbers_sorted.begin(), numbers_sorted.end());
}
};
vector<int> bucket_count(int bucket_size) {
vector<int> ret;
vector<Bucket> buckets;
buckets.resize(int(n / bucket_size) + 5);
for (int i = 0; i < n; i++) {
buckets[i / bucket_size].numbers.push_back(arr[i]);
}
for (int i = 0; i <= n / bucket_size; i++) {
buckets[i].build();
}
for (int i = 0; i < m; i++) {
Query q = queries[i];
char ty = q.ty;
int a, b, c;
a = q.a, b = q.b, c = q.c;
if (ty == 'A') {
set<int> affect_buckets;
while (a < b && a % bucket_size != 0) buckets[a/ bucket_size].add_pos(a % bucket_size, c), affect_buckets.insert(a/bucket_size), a++;
while (a < b && b % bucket_size != 0) buckets[b/ bucket_size].add_pos(b % bucket_size, c), affect_buckets.insert(b/bucket_size), b--;
while (a < b) {
buckets[a/bucket_size].add += c;
a += bucket_size;
}
buckets[a/bucket_size].add_pos(a % bucket_size, c), affect_buckets.insert(a / bucket_size);
for (set<int>::iterator it = affect_buckets.begin(); it != affect_buckets.end(); it++) {
int id = *it;
buckets[id].build();
}
ret.push_back(-1);
} else {
int tmp = 0;
while (a < b && a % bucket_size != 0) tmp += (buckets[a/ bucket_size].query(a % bucket_size) <=c), a++;
while (a < b && b % bucket_size != 0) tmp += (buckets[b/ bucket_size].query(b % bucket_size) <=c), b--;
while (a < b) {
int pos = a / bucket_size;
tmp += upper_bound(buckets[pos].numbers_sorted.begin(), buckets[pos].numbers_sorted.end(), c - buckets[pos].add) - buckets[pos].numbers_sorted.begin();
a += bucket_size;
}
tmp += (buckets[a / bucket_size].query(a % bucket_size) <= c);
ret.push_back(tmp);
}
}
return ret;
}
void process(int cas) {
clock_t begin_t=clock();
vector<int> bf_ans = bruteforce();
clock_t bf_end_t =clock();
double bf_sec = ((1.0 * bf_end_t - begin_t)) / CLOCKS_PER_SEC;
//bucket_size is important
int bucket_size = 200;
vector<int> ans = bucket_count(bucket_size);
clock_t bucket_end_t =clock();
double bucket_sec = ((1.0 * bucket_end_t - bf_end_t)) / CLOCKS_PER_SEC;
bool correct = true;
for (int i = 0; i < ans.size(); i++) {
if (ans[i] != bf_ans[i]) {
cout << "query " << i + 1 << " bf = " << bf_ans[i] << " bucket = " << ans[i] << " bucket size = " << bucket_size << " " << n << " " << m << endl;
correct = false;
}
}
printf("Case #%d:%s bf_sec = %.9lf, bucket_sec = %.9lf\n", cas, correct ? "YES":"NO", bf_sec, bucket_sec);
}
void read() {
cin >> n >> m;
arr.clear();
for (int i = 0; i < n; i++) {
int val;
cin >> val;
arr.push_back(val);
}
queries.clear();
for (int i = 0; i < m; i++) {
char ty;
int a, b, c;
// a, b, c in [0, n - 1], a <= b
cin >> ty >> a >> b >> c;
queries.push_back(Query(ty, a, b, c));
}
}
void run(int cas) {
read();
process(cas);
}
int main() {
freopen("bucket.in", "r", stdin);
//freopen("bucket.out", "w", stdout);
int T;
scanf("%d", &T);
for (int cas = 1; cas <= T; cas++) {
run(cas);
}
return 0;
}
and here are the data gen code:
#coding=utf8
import random
import math
def gen_buckets(f):
t = random.randint(10, 20)
print >> f, t
nlimit = 100000
mlimit = 10000
limit = 100000
for i in xrange(t):
n = random.randint(1, nlimit)
m = random.randint(1, mlimit)
print >> f, n, m
for i in xrange(n):
val = random.randint(1, limit)
print >> f, val ,
print >> f
for i in xrange(m):
ty = random.randint(1, 2)
a = random.randint(0, n - 1)
b = random.randint(a, n - 1)
#a = 0
#b = n - 1
c = random.randint(-limit, limit)
print >> f, 'A' if ty == 1 else 'Q', a, b, c
f = open("bucket.in", "w")
gen_buckets(f)
Try applying a Binary Index Trees (BIT) instead of a segmented tree. Here's the link to the tutorial

Resources