Pagini recente » Cod sursa (job #450138) | Cod sursa (job #697988) | Istoria paginii runda/sh_pregatire_spartanica | Cod sursa (job #191689) | Cod sursa (job #119746)
Cod sursa(job #119746)
#include <cstdio>
#include <vector>
using namespace std;
#define DxBG
#define FL
#define fin "pairs.in"
#define fout "pairs.out"
#define pb push_back
#define sz(c) (int)((c).size())
const int Vmax = 1001100;
const int Nmax = 100100;
int N,MAX,v[Vmax];
int nr[Nmax];
vector <int> divnr[Nmax];
long long cnt1; //cate is bune
long long cnt2; //cate au cmmdc>1
//v[i] - cate numere se divid cu i
//nr - numerele date
//div[i] - divizorii numarului nr[i]
void readdata()
{
int i,a;
freopen(fin,"r",stdin);
scanf("%d",&N);
for (i=1;i<=N;++i)
{
scanf("%d",&a);
v[a]=1;
if ( a > MAX )
MAX = a;
nr[i]=a;
}
}
void solve()
{
int i,j,k,nrb,tmp,bun;
long long cnt;
//aflu fiecare numar "i" cu cate numere din "nr" se divide
for (i=2;i<=MAX;++i)
{
for (j=i+i;j<Vmax;j+=i)
if (v[j])
++v[i];
}
//gata
//aflu divizorii fiecarui numar
for (i=1;i<=N;++i)
{
tmp=nr[i];
for (j=2;j*j<=tmp;++j)
{
bun=0;
while (tmp%j==0)
{
bun=1;
tmp/=j;
}
if (bun)
divnr[i].pb(j);
}
if (tmp>1)
divnr[i].pb(tmp);
}
//gata
#ifdef DBG
for (i=1;i<=MAX;++i)
printf("%d ",v[i]);
printf("\n");
for (i=1;i<=N;++i,printf("\n"))
for (j=0;j<sz(divnr[i]);++j)
printf("%d ",divnr[i][j]);
printf("\n");
#endif
cnt1 = N*(N-1)/2;
cnt2 = 0;
//incep rezolvarea propriu-zisa
for (i=1;i<=N;++i)
{
cnt = 0; //numar perechi care au cmmdc( nr[i] , a ) > 1
//excludere si includere
for (j=1;j<(1<<sz(divnr[i]));++j)
{
nrb = 0;
tmp = 1;
for (k=0;(1<<k)<=j;++k)
if (j&(1<<k))
{
++nrb;
tmp*=divnr[i][k];
}
if (nrb%2!=0)
cnt+=(v[tmp]-1);
else
cnt-=(v[tmp]-1);
}
//gata
cnt2+=cnt;
#ifdef DBG
printf("%d %d\n",i,cnt);
#endif
}
cnt2/=2;
cnt1-=cnt2;
#ifdef FL
freopen(fout,"w",stdout);
#endif
printf("%lld\n",cnt1,cnt2);
}
int main()
{
readdata();
solve();
return 0;
}