#include <bits/stdc++.h>
using namespace std;
void zepchnij(int w, vector<int>&drzewo, int podarunek);
void aktualizuj(int w, int lewy, int prawy, int lprzedzial, int rprzedzial, int prezent, vector<int>&drzewo);
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<int>miasta(n);
for(int i=0; i<n; i++){
cin >> miasta[i];
}
sort(miasta.begin(),miasta.end());
vector<int>liczby;
int obecna=0,licznik=0;
for(int i=0; i<n; i++){
if(obecna == miasta[i]){
licznik++;
}else{
if(licznik!=0)liczby.push_back(licznik);
licznik = 1;
obecna = miasta[i];
}
}
liczby.push_back(licznik);
int wielkosc=1;
while(wielkosc<n){
wielkosc = 2*wielkosc;
}
vector<int>drzewo(2*wielkosc,0);
int lewy, prawy,p1,p2;
for(int i=0; i<liczby.size();i++){
lewy = wielkosc;
for(int j=1; j<=liczby[i];j++){
p1 = liczby[i]/j;
p2 = liczby[i]/(j+1);
if(p1!=p2){
prawy = j+wielkosc-1;
aktualizuj(1, wielkosc, (2*wielkosc)-1, lewy, prawy, p1, drzewo);
lewy = j+wielkosc;
}
}
}
zepchnij(1, drzewo, 0);
for(int i=wielkosc; i<(wielkosc+n);i++){
cout << ((i-wielkosc+1)*drzewo[i]) << " ";
}
cout << endl;
return 0;
}
void zepchnij(int w, vector<int>&drzewo, int podarunek){
drzewo[w]+=podarunek;
if(w < (drzewo.size()/2)){
zepchnij(2*w, drzewo, drzewo[w]);
zepchnij((2*w)+1, drzewo, drzewo[w]);
}
}
void aktualizuj(int w, int lewy, int prawy, int lprzedzial, int rprzedzial, int prezent, vector<int>&drzewo){
if(lewy >= lprzedzial && prawy <= rprzedzial){
drzewo[w]+=prezent;
}else{
if(lewy<=rprzedzial && prawy>=lprzedzial){
aktualizuj(2*w, lewy, (prawy+lewy)/2, lprzedzial, rprzedzial, prezent, drzewo);
aktualizuj((2*w)+1, ((prawy+lewy)/2)+1, prawy, lprzedzial, rprzedzial, prezent, drzewo);
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #include <bits/stdc++.h> using namespace std; void zepchnij(int w, vector<int>&drzewo, int podarunek); void aktualizuj(int w, int lewy, int prawy, int lprzedzial, int rprzedzial, int prezent, vector<int>&drzewo); int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n; cin >> n; vector<int>miasta(n); for(int i=0; i<n; i++){ cin >> miasta[i]; } sort(miasta.begin(),miasta.end()); vector<int>liczby; int obecna=0,licznik=0; for(int i=0; i<n; i++){ if(obecna == miasta[i]){ licznik++; }else{ if(licznik!=0)liczby.push_back(licznik); licznik = 1; obecna = miasta[i]; } } liczby.push_back(licznik); int wielkosc=1; while(wielkosc<n){ wielkosc = 2*wielkosc; } vector<int>drzewo(2*wielkosc,0); int lewy, prawy,p1,p2; for(int i=0; i<liczby.size();i++){ lewy = wielkosc; for(int j=1; j<=liczby[i];j++){ p1 = liczby[i]/j; p2 = liczby[i]/(j+1); if(p1!=p2){ prawy = j+wielkosc-1; aktualizuj(1, wielkosc, (2*wielkosc)-1, lewy, prawy, p1, drzewo); lewy = j+wielkosc; } } } zepchnij(1, drzewo, 0); for(int i=wielkosc; i<(wielkosc+n);i++){ cout << ((i-wielkosc+1)*drzewo[i]) << " "; } cout << endl; return 0; } void zepchnij(int w, vector<int>&drzewo, int podarunek){ drzewo[w]+=podarunek; if(w < (drzewo.size()/2)){ zepchnij(2*w, drzewo, drzewo[w]); zepchnij((2*w)+1, drzewo, drzewo[w]); } } void aktualizuj(int w, int lewy, int prawy, int lprzedzial, int rprzedzial, int prezent, vector<int>&drzewo){ if(lewy >= lprzedzial && prawy <= rprzedzial){ drzewo[w]+=prezent; }else{ if(lewy<=rprzedzial && prawy>=lprzedzial){ aktualizuj(2*w, lewy, (prawy+lewy)/2, lprzedzial, rprzedzial, prezent, drzewo); aktualizuj((2*w)+1, ((prawy+lewy)/2)+1, prawy, lprzedzial, rprzedzial, prezent, drzewo); } } } |
English