Cod sursa(job #2765928)

Utilizator OvidRata Ovidiu Ovid Data 30 iulie 2021 13:27:24
Problema Indep Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.43 kb
#include<bits/stdc++.h>
using namespace std;
#define INIT  ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define mp make_pair
#define pb push_back
#define ft first
#define sc second
#define ll long long
#define pii pair<int, int>
#define count_bits __builtin_popcount
#define int ll


ifstream fin("indep.in"); ofstream fout("indep.out");
#define cin fin
#define cout fout

int n, a[501];
vector<int> pr;


void to_vec(int n, vector<int> &v){
    int x=n;
    v.clear();
    while(x>0){
        v.pb(x%10);
        x/=10;
    }
    if(v.size()==0){
        v.pb(0);
    }
    return;
}


void add(vector<int> v1, vector<int> v2, vector<int> &vf){
    vector<int> v3;
    v3.pb(0);
    for(int i=0; i<(max((int)v1.size(), (int) v2.size() )); i++)
    {
        if(i>=((int)v1.size()) ){
            v3.pb(0);
            v3[i]+=v2[i];
            v3[i+1]+=v3[i]/10;
            v3[i]%=10;
        }
        else{
            if(i>=((int) v2.size()) ){
                v3.pb(0);
                v3[i]+=v1[i];
                v3[i+1]+=v3[i]/10;
                v3[i]%=10;
            }
            else{
        v3.pb(0);
        v3[i]+=v1[i]+v2[i];
        v3[i+1]+=v3[i]/10;
        v3[i]%=10;
            }
        }

    }
    while( (v3.back()==0) && (v3.size()>1) ){
        v3.pop_back();
    }
    vf=v3;
    return;
}


void multip(vector<int> v1, vector<int> v2, vector<int> &vf){

vector<int> v3; v3.assign((int)(v1.size())+((int)v2.size())+10, 0);

for(int i=0; i<v1.size(); i++){
    for(int j=0; j<v2.size(); j++){
        v3[i+j]+=v1[i]*v2[j];
    }
}

for(int i=0; i<(((int)v3.size())-1); i++){
    v3[i+1]+=v3[i]/10;
    v3[i]%=10;
}

while( (v3.back()==0) && (v3.size()>1) ){
    v3.pop_back();
}


vf=v3;

}



//v1-v2
void subtract(vector<int> v1, vector<int> v2, vector<int> &vf){
vector<int> v3;
v3.pb(0);
for(int i=0; i<( max( ((int)v1.size() ), (int)v2.size()  )  ); i++){
    if(i>=(v1.size()) && (i>=v2.size())  ){break;}
    if( i>=((int)v1.size())  ){
        v3.pb(0);
        v3[i]-=v2[i];

        if(v3[i]<0){
            v3[i+1]+=v3[i]/10; v3[i+1]--;
            v3[i]=(10-( (abs(v3[i])%10) ))%10;
        }
        else{
            v3[i]=v3[i]%10;
        }
    }
    else{

        if(i>=((int)v2.size())){
            v3.pb(0);
            v3[i]+=v1[i];

            if(v3[i]<0){
                v3[i+1]+=v3[i]/10; v3[i+1]--;
                v3[i]=( 10- (abs(v3[i])%10 )  )%10;
            }
            else{
                v3[i]=v3[i]%10;
            }
        }
        else{
            v3.pb(0);
            v3[i]+=v1[i]-v2[i];

            if(v3[i]<0){
                v3[i+1]+=v3[i]/10; v3[i+1]--;
                v3[i]=( 10- (abs(v3[i])%10 )  )%10;
            }
            else{
                v3[i+1]+=v3[i]/10;
                v3[i]=v3[i]%10;
            }
        }

    }

    //cout<<"ok"<<flush;

}

while( (v3.back()==0) && (v3.size()>1) ){
        v3.pop_back();
    }
    vf=v3;

}




void get_primes(vector<int> &v){
    bool sv[1001]; memset(sv, 0, sizeof(sv));

    for(int i=2;i<=1000; i++){
        if(sv[i]==false){
            v.pb(i);
            for(int j=i*2; j<=1000; j+=i){
                sv[j]=true;
            }
        }
    }
    return;
}



int D[1001];
vector<int> Z[1001];
vector<int> P2[1001];

void build_D(){

for(int i=1; i<=n; i++){
    for(int j=1; j<=sqrt(a[i]); j++){
        if( (a[i]%j)==0 ){
            D[j]++;
            if( (a[i]/j)!=j ){
                D[a[i]/j ]++;
            }
        }
    }
}


}


void build_z(){

//vector<int> v0;
to_vec(1, P2[0]);
for(int i=1; i<=500; i++){
    vector<int> v0; to_vec(2, v0);
    multip(P2[i-1], v0, P2[i]);
}


for(int i=1; i<=1000; i++){
    Z[i]=P2[D[i] ];
    vector<int> v0; to_vec(1, v0);
    subtract(Z[i], v0, Z[i]);
}

return;
}


vector<int> sums[1001];


void comb(int cnt, int b, int prod){

if(prod>1000){
    return;
}
if(b==(pr.size() ) ){
    add(sums[cnt], Z[prod], sums[cnt ]);
    return;
}


for(int i=0; i<=1; i++){
    comb(cnt+(1)*i, b+1, prod*((i==1)?(pr[b]):(1)) );
}


}


void inc_exc(vector<int> &vf ){
vector<int> res1;
vector<int> res2;
to_vec(0, res1);
to_vec(0, res2);
for(int i=1; i<=pr.size(); i++){
    if( (i%2)==0 ){
        add(res2, sums[i], res2);
    }
    else{
        add(res1, sums[i], res1);
    }
}
vector<int> res3;
subtract(res1, res2, res3);
vf=res3;
return;
}





void output(vector<int> nr){
    for(int i=(((int)nr.size())-1); i>=0; i--){
        cout<<nr[i];
    }
    cout<<"\n"<<flush;
}




int32_t main(){
INIT



/*
vector<int> v1, v2;
to_vec(14823474, v1);
to_vec(1315914, v2);
multip(v1, v2, v1);
output(v1);
add(v1, v2, v1);
output(v1);
subtract(v1, v2, v1);
output(v1);
*/





cin>>n;
for(int i=1; i<=n; i++){
    cin>>a[i];
}
get_primes(pr);
//cout<<"gpr\n"<<flush;
build_D();
//cout<<"D\n"<<flush;
build_z();
//cout<<"Z\n"<<flush;
for(int i=0; i<=1000; i++){
    to_vec(0, sums[i]);
}
comb(0, 0, 1);
//cout<<"comb\n"<<flush;
vector<int> ie;

inc_exc(ie);
//cout<<"ie\n"<<flush;
vector<int> res;
//output(P2[n]);
//output(ie);
subtract(P2[n], ie, res);

vector<int> v0;
to_vec(1, v0);
subtract(res, v0, res);


output(res);




return 0;
}