TRIO - Editorial

PROBLEM LINK:

Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4

Author: ro27
Tester: jay_1048576
Editorialist: iceknight1093

DIFFICULTY:

TBD

PREREQUISITES:

None

PROBLEM:

Given an array A, find the number of pairs of indices i \lt j such that:

  • The sequence (A_i-A_j, A_i+A_j, A_i\times A_j) is an arithmetic progression.

EXPLANATION:

Suppose, for some indices i and j, the sequence (A_i-A_j, A_i+A_j, A_i\times A_j) is an arithmetic progression.
Let’s see what that tells us about the values of A_i and A_j.

A bit of algebra

Three numbers being in AP is equivalent to saying that twice the middle number equals the sum of the other two.
So, we have 2\cdot (A_i + A_j) = (A_i - A_j) + (A_i\cdot A_j).
Simplifying this a bit,

2\cdot (A_i + A_j) = (A_i - A_j) + (A_i\cdot A_j) \\ A_i + 3A_j = A_i\cdot A_j \\ A_i = A_j\cdot (A_i - 3)

Now, we use the fact that all the A_i are positive integers.
The above equation tells us that A_i - 3 must be a factor of A_i.
However, this can only happen when A_i = 4, or A_i = 6.
For A_i \geq 7, A_i-3 is too large to be a proper divisor of A_i.

When A_i = 4, we get A_j = 4.
When A_i = 6, we get A_j = 2.
(Technically, A_i = 2 also has 2-3 = -1 as a divisor, but that would result in negative A_j so it can be ignored).

So, the only valid pairs of elements are (6, 2) and (4, 4)!

So, the problem reduces to counting the number of pairs (i, j) such that (A_i, A_j) = (4, 4) or (6, 2).
That’s fairly straightforward to do:

  • Let c_4 and c_6 denote the number of 4's and 6's seen so far.
  • For each i from 1 to N,
    • If A_i = 2, add c_6 to the answer.
    • If A_i = 4, add c_4 to the answer, then increment c_4 by one.
    • If A_i = 6, increment c_6 by 1.
    • Anything else can be ignored.

TIME COMPLEXITY:

\mathcal{O}(N) per testcase.

CODE:

Author's code (C++)
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<class T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// order_of_key(a)  -> gives index of the element(number of elements smaller than a)
// find_by_order(a) -> gives the element at index a
#define accelerate ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define int        long long int
#define ld         long double
#define mod1       998244353
#define endl       "\n"
#define ff         first
#define ss         second
#define all(x)     (x).begin(),(x).end()
#define ra(arr,n)  vector<int> arr(n);for(int in = 0; in < n; in++) {cin >> arr[in];}


const int mod = 1e9 + 7;
const int inf = 1e18;
int MOD(int x) {int a1 = (x % mod); if (a1 < 0) {a1 += mod;} return a1;}
int N = 2e5;
vector<int>yep(N + 1, true);
int power( int a,  int b) {
    int p = 1; while (b > 0) {if (b & 1)p = (p  * a); a = (a * a )    ; b >>= 1;}
    return p ;
}

void lessgoo()
{
    int n;
    cin >> n;
    ra(arr, n);
    int a = 0, ans = 0, f = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] == 4)f++;
        else if (arr[i] == 6)a++;
        else if (arr[i] == 2) {
            ans += a;
        }
    }
    cout << ans + f*(f - 1) / 2 << endl;
}

signed main()
{
    accelerate;

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif


    int test = 1;
    cin >> test ;
    for (int tcase = 1; tcase <= test; tcase++)
    {
        // cout << "Case #" << tcase << ": ";

        lessgoo();

    }
    return 0;
}
Editorialist's code (Python)
for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    ans = 0
    c4, c6 = 0, 0
    for x in a:
        if x == 4:
            ans += c4
            c4 += 1
        if x == 2: ans += c6
        if x == 6: c6 += 1
    print(ans)
1 Like

i think 3aj=ai(aj-1) is more easy to understand i mean it just feel better, and aj>1

This post was flagged by the community and is temporarily hidden.

Why is my code giving tle when the time limit is 1sec.
include <bits/stdc++.h>
using namespace std;

int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin>>t;
for(int i=0;i<t;i++){
int n;
cin>>n;
int a[n];
vector<pair<int,int>>w;
for(int j=0;j<n;j++){
cin>>a[j];
pair<int,int>r;
r.first=a[j];
r.second=j;
w.push_back(r);
}
sort(w.begin(),w.end());
int count=0;
for(int j=1;j<n;j++){
if(a[j]%2==0){
int target=(3*a[j])/(a[j]-1);
int start=0,end=n-1;
while(start<=end){
int mid=start+(end-start)/2;
if((w[mid].first==target)){
if(w[mid].second<j){
count++;
break;
}
}
else if(w[mid].first>target){
end=mid-1;
}
else{
start=mid+1;
}
}
}
}
cout<<count<<‘\n’;
}
// your code goes here

}

For the formula 2⋅(Ai+Aj)=(Ai−Aj)+(Ai⋅Aj) it may be necessary to specify that a, b, c are consecutive terms of an arithmetic progression with a <= b <= c