Ciao a tutti,
ho risolto con successo Combinazioni totalizzando 100/100, tuttavia non riesco a capire quale possa essere la complessità del mio algoritmo. La prima parte del programma è il crivello di Eratostene che funziona in \mathcal O(N \log \log N). Per la seconda parte, sono fermo ad una complessità \mathcal O(N ^ 2). Tuttavia questo algoritmo riesce a superare il subtask con N < 1000000, che richiederebbe una complessità di circa \mathcal O(N). Per qualche ragione il second ciclo for viene eseguito in media \mathcal log N volte. Qualcuno riuscirebbe a spiegarmi o a dimostrare perchè questo algoritmo è così efficente?
Questo è il mio programma:
#include<bits/stdc++.h>
using namespace std;
vector<bool> prime;
void suddividi(int N, int* X, int* Y) {
int scam;
prime.resize(4*N+10);
prime[0] = prime[1] = true;
for(int i=2;i*i<prime.size();i++){
if(!prime[i]){
for(int j=i*i;j<prime.size();j+=i){
prime[j] = true;
}
}
}
for(int i=0;i<N;i++){
X[i] = 2*i+1;
Y[i] = 2*i+2;
}
for(int i=0;i<N;i++){
if(!prime[X[i] + Y[i]]) continue;
for(scam = i + 1 ;prime[X[scambio] + Y[i]] || prime[X[i] + Y[scambio]];scambio--);
swap(Y[i],Y[scambio]);
}
return ;
}