Skip to content

Commit 6743fb9

Browse files
authored
Merge pull request #1 from lightoj-dev/main
updating fork
2 parents bf5f253 + 0ccd94b commit 6743fb9

File tree

16 files changed

+1606
-0
lines changed

16 files changed

+1606
-0
lines changed

1001/en.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# LOJ 1001 - Opposite Task
2+
3+
In this problem, you are given `T` test cases. Each test case contains an integer `n`, the value of which is `20` at max. Your task is to print out two non-negative integers `a` and `b`, such that `n = a + b`. Any values of `a` and `b` that satisfies the equation is accepted, however, neither of `a` nor `b` can be greater than `10`.
4+
5+
It is one of the easiest problems on LightOJ volumes. However, some people might find it difficult to get an `Accepted` verdict. The reason could be one of the following:
6+
1. Printing a number greater than 10
7+
2. Failing to provide proper output format
8+
3. Missing new line on each line
9+
10+
If you are still stuck with this problem, check the codes below:
11+
12+
### C
13+
-----
14+
```c
15+
#include <stdio.h>
16+
int main() {
17+
int T, n;
18+
scanf("%d", &T);
19+
for (int i = 1; i <= T; i++) {
20+
scanf("%d", &n);
21+
if (n > 10) {
22+
printf("10 %d\n", n - 10);
23+
} else {
24+
printf("0 %d\n", n);
25+
}
26+
}
27+
return 0;
28+
}
29+
```
30+
31+
### Java
32+
-----
33+
```java
34+
package com.loj.volume;
35+
36+
import java.util.Scanner;
37+
38+
class OppositeTask {
39+
public static void main(String[] args) throws Exception {
40+
Scanner scanner = new Scanner(System.in);
41+
int T = scanner.nextInt(), n;
42+
for (int i = 1; i <= T; i++) {
43+
n = scanner.nextInt();
44+
if (n > 10) {
45+
System.out.printf("10 %d\n", n - 10);
46+
} else {
47+
System.out.printf("0 %d\n", n);
48+
}
49+
}
50+
}
51+
}
52+
```

1007/en.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# LOJ 1007 - Mathematically Hard
2+
3+
_You have given `T` test cases and for each test case you have `a`, the lower bound, and `b`, the upper bound, find the summation of the
4+
scores of the numbers from a to b (inclusive), where <br>
5+
score (x) = n<sup>2</sup>,where n is the number of relatively prime numbers with x, which are smaller than x._
6+
7+
---
8+
9+
### Summary
10+
11+
This is a number theory problem and for the `T` group of the input set, where each set consists of `a` and `b`, you have to find,square sum of all Euler function values from `a` to `b`.
12+
13+
### Solution
14+
15+
Before you get to the solution let's have some idea about `Euler's totient function` aka `phi`.<br>
16+
17+
```
18+
Euler's totient function, also known as phi-function `ϕ(n)`, counts the number of integers between `1` and `n` inclusive, which are `coprime` to `n`. Two numbers are coprime if their greatest common divisor equals `1` (`1` is considered to be coprime to any number).
19+
```
20+
21+
Have a look:
22+
23+
- [wikipedia: Euler's totient function](https://en.wikipedia.org/wiki/Euler%27s_totient_function)
24+
- [cp-algorithms: Euler's totient function](https://cp-algorithms.com/algebra/phi-function.html)
25+
26+
- [A quite useful cheat-sheet of CP: Phi Implementation](https://github.com/ar-pavel/CP-CheatSheet#631-euler-function)
27+
28+
Using Euler's totient function, calculate number of coprime for all the numbers until max possible input. Now, let's assume you have `phi[]` array that contains all the `ϕ(n)` values. As you will need to print the sum of square values of the `ϕ(n)`, loop through the `phi[]` array and multiply them with own value (`phi[i] = phi[i]*phi[i]`). Now your `phi[]` array contains square values of each `ϕ(n)`. For each query, as you need to print `sum(phi[a] ... phi[b])`, you can optimize this process by generating a [cumulative sum array](https://www.tutorialspoint.com/cplusplus-program-for-range-sum-queries-without-updates) of of `phi[]`.
29+
30+
The algorithm is:
31+
32+
- find all Phi values from `1 - rangeMax`
33+
- calculate square value of each of them
34+
- generate cumulative sum array of squared phi values
35+
- for each query, print the `cumulative sum array[b]` - `cumulative sum array [a-1]`
36+
37+
### C++
38+
-----
39+
```cpp
40+
#include <bits/stdc++.h>
41+
42+
using namespace std;
43+
44+
#define M 5000000
45+
46+
int phi[M+2];
47+
unsigned long long phiSum[M+2];
48+
49+
void calculatePhi(){
50+
for(int i=2; i<=M; i++)
51+
phi[i] = i;
52+
for(int i =2; i<=M; i++)
53+
if(phi[i]==i)
54+
for(int j=i; j<=M; j+=i)
55+
phi[j]-=phi[j]/i;
56+
}
57+
58+
int main(){
59+
60+
calculatePhi();
61+
phiSum[1] = 0;
62+
63+
for(int i=2; i<=M; i++)
64+
phiSum[i]= ((unsigned long long)phi[i]* (unsigned long long)phi[i])+phiSum[i-1];
65+
66+
// for(int i=1; i<10; ++i)
67+
// cout<<phi[i]<<" "<<phiSum[i]<<endl;
68+
// deb(phi[2]);
69+
// deb(phiSum[20]);
70+
71+
int tc,t(1);
72+
for(scanf("%d",&tc); tc; ++t,--tc){
73+
int a,b;
74+
scanf("%d%d",&a,&b);
75+
unsigned long long x = phiSum[b]-phiSum[a-1];
76+
printf("Case %d: %llu\n",t,x);
77+
}
78+
return 0;
79+
}
80+
```

1014/en.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# 1014 - Ifter Party
2+
3+
_You have given `T` test cases and for each test case you have `P`, number of piaju in the beginning, and `L` piaju left end of the day, find the value `Q`, the number of piaju's each of `C` contestant ate._
4+
5+
---
6+
7+
### Summary
8+
9+
This is a number theory problem and for the `T` group of the input set, where each set consists of `P` and `L` number, you have to find all the divisors of piaju's eaten or `(P-L)`.
10+
11+
### Solution
12+
13+
Initially, you had `P` amount of piaju's, and end of the day it became `L`, so piaju's eaten by the contestants are `(P-L)`. As `C` contestants were invited and each of them ate `Q` piaju's each, `P - L = C * Q` stands true. So the result will be all possible divisors of `Q`, the number of piaju's each contestant ate.
14+
15+
The algorithm is:
16+
17+
- find the number of piaju's eaten
18+
- find all the unique divisors of the 'count of eaten piaju's'
19+
- sort and print all the divisors in ascending order that satisfy `(L<Q)` condition.
20+
- if no such solution exists print `impossible`.
21+
22+
### Code
23+
24+
#### C++
25+
26+
```cpp
27+
#include <bits/stdc++.h>
28+
29+
using namespace std;
30+
31+
int main(){
32+
#ifndef ONLINE_JUDGE
33+
freopen("in.txt","r",stdin);
34+
freopen("out.txt","w",stdout);
35+
#endif
36+
37+
int tc,t(1);
38+
for(scanf("%d",&tc); tc; ++t,--tc){
39+
long long piaju,left;
40+
41+
scanf("%lld%lld", &piaju,&left);
42+
43+
// exception
44+
if(left*2>=piaju){
45+
printf("Case %d: impossible\n",t);
46+
continue;
47+
}
48+
49+
printf("Case %d:",t);
50+
51+
52+
long long piajuEaten = piaju-left;
53+
// cout<<piajuEaten<<endl;
54+
55+
vector<long long> possibleValueOfQ;
56+
57+
58+
// find all the divisors of piajuEaten
59+
for(long long i=1; i*i<=piajuEaten; ++i)
60+
if(piajuEaten%i==0){
61+
possibleValueOfQ.push_back(i);
62+
63+
if(piaju/i!=i)
64+
possibleValueOfQ.push_back(piajuEaten/i);
65+
}
66+
67+
// sort the divisors to print the answer in ascending order
68+
sort(possibleValueOfQ.begin(), possibleValueOfQ.end());
69+
70+
// print the divisors
71+
for(auto x: possibleValueOfQ)
72+
// if(x>left)
73+
printf(" %lld",x);
74+
75+
76+
printf("\n");
77+
}
78+
79+
return 0;
80+
}
81+
82+
```

1029/en.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# LOJ 1029 - Civil and Evil Engineer
2+
3+
### Problem Summary
4+
5+
You have `n` houses `[1-n]` and a power station `0`. You are also given a set of wires, where every wire is in `u v w` format, meaning `connection from u to v costs w`. You have to use exactly `n` wires from the set to connect the houses with the power station. **The connections can be direct or indirect (through some houses) but there must be a path of wires from every house to the power station.**
6+
7+
### Observations
8+
9+
We can see the following properties in the problem structure.
10+
11+
- **Graph**: We can consider the houses and the power station as `nodes` in a graph, and the wires as `edges`. Since the costs of connecting two nodes are given, and the connections have no direction, so this is a `Weighted Undirected Graph`.
12+
13+
- **Tree**: In total, we have `n+1` nodes (`n` houses and `1` power station). We have to connect them using exactly `n` wires or `edges`. We know in a tree, for `N` nodes we have `N-1` edges. So the problem is asking us to convert the graph into a tree.
14+
15+
- **Minimum Spanning Tree**: For the `best possible connection scheme`, We have to connect all houses with the power station using minimum cost. We have to pick `edges` in a way that satisfies the cost minimization. Therefore, we have to compute the `Minimum Spanning Tree` of the graph.
16+
17+
- `Minimum Spanning Tree` of a graph is a subtree of that graph that contains all the `nodes` and the `sum of edge weights` is minimum possible. You can use [Prim's algorithm](https://cp-algorithms.com/graph/mst_prim.html) or [Kruskal's Algorithm](https://cp-algorithms.com/graph/mst_kruskal.html) to implement the Minimum Spanning Tree.
18+
19+
- **Maximum Spanning Tree**: We also have to calculate the maximum possible cost to connect all the `nodes`, since this is the `worst possible connection scheme`. For this, we have to pick `edges` in a way that maximizes the cost. So we also have to compute the `Maximum Spanning Tree` of the graph.
20+
- `Maximum Spanning Tree` of a graph is a subtree of that graph that contains all the `nodes` and the `sum of edge weights` is maximum possible. We can tweak the Minimum Spanning Tree algorithm (sort the edges in descending order of the weights) to implement Maximum Spanning Tree.
21+
22+
### Solution
23+
24+
For every case, we have to calculate minimum spanning tree `cost1` and maximum spanning tree `cost2` and then average their costs, thus `(cost1 + cost2) / 2`. If `(cost1 + cost2)` is not divisible by `2` then we have to print in `p/q` format. Where `p` is `(cost1 + cost2)` and `q` is `2`. For example, `229/2`.
25+
26+
### Simulation
27+
28+
Simulation of **test case 2** is given below.
29+
30+
![Frame 1](https://user-images.githubusercontent.com/14056189/99875765-3bdd5700-2c1c-11eb-970f-92222ebe7c22.png)
31+
32+
![Frame 2](https://user-images.githubusercontent.com/14056189/99876684-8792ff00-2c22-11eb-8a0a-6fe3ee6bc73f.png)
33+
34+
![Frame 3](https://user-images.githubusercontent.com/14056189/99875768-3f70de00-2c1c-11eb-80d2-38ab56236789.png)
35+
36+
And the answer is `(70 + 159) / 2`. Since `229` is not divisible by `2`, we print `229/2`.
37+
38+
### C++
39+
40+
---
41+
42+
```C++
43+
#include<bits/stdc++.h>
44+
using namespace std;
45+
46+
struct edge{
47+
int u, v, w;
48+
};
49+
50+
bool cmp(edge A, edge B){
51+
return A.w < B.w;
52+
}
53+
54+
// edge list
55+
vector < edge > G;
56+
57+
int n; // total nodes
58+
int parent[105];
59+
60+
// function to clear graph
61+
void _init(){
62+
G.clear();
63+
}
64+
65+
// function to find parent of a disjoint set
66+
int Find(int u){
67+
if (u==parent[u]) return u;
68+
return parent[u] = Find(parent[u]);
69+
}
70+
71+
// Kruskal's algorithm with Disjoint-Set Union method is used
72+
// minimum spanning tree
73+
long long MinST(){
74+
// reset parent table [0-n]
75+
for (int i = 0; i <= n; i++)
76+
parent[i] = i;
77+
78+
long long cost = 0;
79+
// forward iteration for minimum cost first
80+
for (int i = 0; i < G.size(); i++){
81+
int u = G[i].u;
82+
int v = G[i].v;
83+
int w = G[i].w;
84+
85+
int p = Find(u);
86+
int q = Find(v);
87+
if (p!=q){
88+
cost += w;
89+
parent[q] = p;
90+
}
91+
}
92+
return cost;
93+
}
94+
95+
// maximum spanning tree
96+
long long MaxST(){
97+
// reset parent table [0-n]
98+
for (int i = 0; i <= n; i++)
99+
parent[i] = i;
100+
101+
long long cost = 0;
102+
// backward iteration for maximum cost first
103+
for (int i = G.size()-1; i >= 0; i--){
104+
int u = G[i].u;
105+
int v = G[i].v;
106+
int w = G[i].w;
107+
108+
int p = Find(u);
109+
int q = Find(v);
110+
if (p!=q){
111+
cost += w;
112+
parent[q] = p;
113+
}
114+
}
115+
return cost;
116+
}
117+
118+
int main()
119+
{
120+
int T; scanf("%d", &T);
121+
for (int cs = 1; cs <= T; cs++){
122+
_init(); // reset graph
123+
124+
scanf("%d", &n);
125+
int u, v, w;
126+
127+
// take input until all u, v, w are zero (0)
128+
while ( scanf("%d%d%d", &u, &v, &w) && (u!=0 || v!=0 || w!=0) ){
129+
G.push_back({u, v, w});
130+
}
131+
132+
// sorting is only done once
133+
// forward and backward iterations will be done
134+
// for ascending and descending order traversal
135+
sort(G.begin(), G.end(), cmp);
136+
137+
long long cost1 = MinST();
138+
long long cost2 = MaxST();
139+
140+
long long cost = cost1 + cost2;
141+
if (cost%2 == 0) printf("Case %d: %lld\n", cs, cost/2);
142+
else printf("Case %d: %lld/2\n", cs, cost); // cost/2 format
143+
}
144+
return 0;
145+
}
146+
```

1062/1.png

7.66 KB
Loading

1062/2.jpg

18.1 KB
Loading

1062/3.jpg

17.3 KB
Loading

0 commit comments

Comments
 (0)