////Code from: https://codeit.bg/eng/rounds/standings/92 #include #define ll long long #define ld long double using namespace std; int n,m,kds,spar_1=1,npoz,brojKomandi,minPotrebno,redosled[1005][50005],val,total,salji2[50005],coef,ct; int tip=0; ll donajb; struct komande{ int x1,y1,x2,y2,q; }ispis[1000005]; struct cord{ ll x,y,value; }grupe[50005],kule[50005],ntac,trenutna[1005]; map,int> uIndeks,uIndeks2; struct KDcvor{ cord poz; int deca[2],tip,par; int indeks; /// Indeks prvog u nizu sa tom koordinatom int nx,ny,kol; int xu,xl,yu,yl;/// xu - x upper bound, slicno i ostali /// Tip 0 poredi po x, tip 1 po y }KDstablo[300005]; void dodajKomandu(int x1, int y1, int x2, int y2, int q){ ispis[brojKomandi].x1=x1; ispis[brojKomandi].y1=y1; ispis[brojKomandi].x2=x2; ispis[brojKomandi].y2=y2; ispis[brojKomandi].q=q; } ll crkli(long long q, long long p){ return ceil(sqrt(q*q-p*p)); } ll binarna(int koji, int indeks, ll preziveli){ int l=1,r=50000000,sol; while(l<=r){ int s=(l+r)/2; if(crkli(s,kule[redosled[koji][indeks]].value)b.value; } ll kolikoMiTreba(int koji){ int preziveli=0; int x; (tip==4 or tip==1 ? x=49999 : x=n/val-1); for(int i=x; i>=0; i--){ preziveli=binarna(koji,i,preziveli); salji2[i]=preziveli; } return preziveli; } ll kolikoMiTreba2(bool swc){ int preziveli=0; int x,y; (swc ? x=coef : x=49999); (swc ? y=0 : y=coef); for(int i=x; i>=y; i--){ preziveli=binarna(0,i,preziveli); } return preziveli; } ll pitagora(cord a,cord b){ ///Nadje kvadratno rastojanje, ne radi koren a.x-=b.x; a.y-=b.y; return a.x*a.x+a.y*a.y; } pair postaviPored(int indeks){ if(kule[indeks].x==0)return make_pair(kule[indeks].x+1,kule[indeks].y); else return make_pair(kule[indeks].x-1,kule[indeks].y); } void KDupdate(int gde){ if(gde==0) return; int d1,d2; KDstablo[gde].nx=gde; d1=KDstablo[gde].deca[0]; d2=KDstablo[gde].deca[1]; d1=KDstablo[d1].nx; d2=KDstablo[d2].nx; if(KDstablo[d1].poz.x=tacka.x){ p1.x=tacka.x; p2.x=tacka.x; p3.x=tacka.x; p4.x=tacka.x; } if(KDstablo[koren].yl<=tacka.y and KDstablo[koren].yu>=tacka.y){ p1.y=tacka.y; p2.y=tacka.y; p3.y=tacka.y; p4.y=tacka.y; } ll d2=pitagora(tacka,p1); d2=min(d2,pitagora(tacka,p2)); d2=min(d2,pitagora(tacka,p3)); d2=min(d2,pitagora(tacka,p4)); // cout<=donajb) /// Ukoliko ne vredi proveravati ovog return; //cout<d){ donajb=d; npoz=koren; ntac=KDstablo[koren].poz; } int idem=0; KDnadjinajblizeg(KDstablo[koren].deca[idem],tacka); idem^=1; KDnadjinajblizeg(KDstablo[koren].deca[idem],tacka); return; } void KDinit(){ KDstablo[0].nx=0; KDstablo[0].ny=0; KDstablo[0].poz.x=1e18; KDstablo[0].poz.y=1e18; KDstablo[0].par=0; KDstablo[0].deca[0]=0; KDstablo[0].deca[1]=0; KDstablo[0].tip=0; KDstablo[0].xu=KDstablo[0].yu=-2e9-1000; KDstablo[0].xl=KDstablo[0].yl=2e9+1000; KDnovi(2e9+1000,2e9+1000,1,0,0); } void input(){ //Unesi grupe i vojnike freopen("war.in","r",stdin); freopen("war.out","w",stdout); scanf("%d%d",&n,&m); scanf("%lld%lld%lld",&grupe[0].x,&grupe[0].y,&grupe[0].value); for(int i=1; i4690)tip=4; else if(kule[i].value>1360 and tip<4)tip=3; else if(kule[i].value>360 and tip<3)tip=2; else if(kule[i].value>100 and tip<2)tip=1; } //Pokreni KDTree KDinit(); //Ako se radi na drugi nacin, treba napraviti mapu indeksa i dodati kule u KDTree if(tip==4){ KDinit(); sort(kule,kule+50000,cmp); coef=35000; for(int i=0; i=coef)KDdodaj(1,kule[i],i); KDdodaj(2,grupe[i],i); uIndeks[make_pair(kule[i].x,kule[i].y)]=i; uIndeks2[make_pair(grupe[i].x,grupe[i].y)]=i; } } else if(tip>=2){ KDinit(); for(int i=0; i1360, pronadji optimalan broj vojnika i redosled slanja if(tip==4){ trenutna[0].x=grupe[0].x; trenutna[0].y=grupe[0].y; for(int i=coef; i=2){ (tip==2 ? val=200 : val=16); //Pronadji optimalan redosled slanja for(int i=0; i=2){ for(int i=0; i gdeDaPostavim=postaviPored(redosled[0][i]); koliko=binarna(0,redosled[0][i],max(kule[redosled[0][i+1]].value,kule[redosled[0][i]].value)); while(true){ donajb=4e18; KDnadjinajblizeg(1,kule[redosled[0][i]]); int koji=uIndeks[make_pair((int)ntac.x,(int)ntac.y)]; if(grupe[koji].value==0){ KDizbaci(1,ntac.x,ntac.y); continue; } sakupljeni+=grupe[koji].value; if(sakupljeni gdeDaPostavim=postaviPored(i); koliko=kule[i].value; while(true){ donajb=4e18; //cout << sakupljeni << " " << kule[i].value << endl; KDnadjinajblizeg(1,kule[i]); if(grupe[uIndeks[make_pair((int)ntac.x,(int)ntac.y)]].value==0){ KDizbaci(1,ntac.x,ntac.y); continue; } sakupljeni+=grupe[uIndeks[make_pair((int)ntac.x,(int)ntac.y)]].value; if(sakupljeni