Cod sursa(job #795963)

Utilizator harababurelPuscas Sergiu harababurel Data 9 octombrie 2012 22:00:31
Problema Pairs Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

ifstream f("pairs.in");
ofstream g("pairs.out");

#define nmax 100005
#define sqrtMax 1005
#define Valmax 1000000
#define ll long long

int n, a[nmax], desc[25], prim[sqrtMax], nr[Valmax];
bool viz[sqrtMax];

void citeste(){

	f >> n;
	for(int i=1; i<=n; ++i){
        f >> a[i];
	}

}

void fa_ciur(){

    for(int i=2; i<sqrtMax; ++i){
        if (viz[i] == 0){
            prim[++prim[0]] = i;
            for(int j=i*2; j<sqrtMax; j+=i){
                viz[j] = 1;
            }
        }
    }

}

void rezolva(){

    //ideea ar fi cate perechi exista a. i. cmmdc-ul lor sa fie 1
    //=> iau fiecare numar si vreau sa vad cate numere sunt in stanga lui fata de care e prim
    //=> asa ca ma folosesc de principiul includerii/excluderii pentru a afla cu cate numere din stanga lui i e divizibil

    fa_ciur();
    int Rez = 0;
    for(int i=1; i<=n; ++i){
        desc[0] = 0;
        //il descompun pe a[i] in factori primi
        int X = a[i];
        int j = 1;
        while(X > 1 && j<=prim[0]){
            if ( X % prim[j] == 0 ){
                while( X % prim[j] == 0 ){
                    X = X / prim[j];
                }
                desc[++desc[0]] = prim[j];
            }
            ++j;
        }
        if (X > 1){ desc[++desc[0]] = X; }

        //acum vreau sa vad cu cate numere din stanga lui e divizil
        int cati = 0;
        for(int conf=1; conf<(1<<desc[0]); ++conf){
            int prod = 1;
            int cnt = 0;
            for(int j=0; j<desc[0]; ++j){
                if ( ( conf &(1<<j) ) != 0 ){
                    prod = prod * desc[j+1];
                    ++cnt;
                }
            }
            if (cnt & 1 != 0){//daca e impar
                cati += nr[prod];
            }else cati -= nr[prod];
            ++nr[prod];
        }
        //variabila cati imi zice cu cate numer e divizibil
        Rez = Rez + ((i-1) - cati);
    }

    //cout << Rez << "\n";
    g << Rez << "\n";

}

int main(){

    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;

}