Pagini: [1]   În jos
  Imprimă  
Ajutor Subiect: 1015 Xp  (Citit de 2714 ori)
0 Utilizatori şi 1 Vizitator pe acest subiect.
stef2n
Nu mai tace
*****

Karma: 218
Deconectat Deconectat

Mesaje: 641



Vezi Profilul
« : Aprilie 11, 2010, 10:59:37 »

Aici puteti discuta despre problema Xp.
Memorat

Exista 10 categorii de oameni: cei care inteleg sistemul binar si cei care nu il inteleg.
S7012MY
Nu mai tace
*****

Karma: 26
Deconectat Deconectat

Mesaje: 648



Vezi Profilul
« Răspunde #1 : Noiembrie 22, 2010, 17:28:40 »

Exista vreo proprietate pt (a/b) %p ?
Memorat
pauldb
Nu mai tace
*****

Karma: 821
Deconectat Deconectat

Mesaje: 1.901



Vezi Profilul
« Răspunde #2 : Noiembrie 22, 2010, 18:18:48 »

Citeste aici.
Memorat

Am zis Mr. Green
toni2007
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« Răspunde #3 : Noiembrie 22, 2010, 18:32:26 »

Se face si fara invers modular, in o(n).
Memorat
S7012MY
Nu mai tace
*****

Karma: 26
Deconectat Deconectat

Mesaje: 648



Vezi Profilul
« Răspunde #4 : Noiembrie 22, 2010, 18:53:17 »

Multumesc mult Very Happy 
Ma intereseaza ceva fara invers modular(daca exista)
Memorat
toni2007
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« Răspunde #5 : Noiembrie 22, 2010, 20:49:26 »

Imparti in bucati de sqrt.
Memorat
S7012MY
Nu mai tace
*****

Karma: 26
Deconectat Deconectat

Mesaje: 648



Vezi Profilul
« Răspunde #6 : Noiembrie 26, 2010, 16:00:21 »

Am citit solutia oficiala si nu spune nimic despre invers modular. Poate cineva sa descrie solutia cu invers modular?    peacefingers
Memorat
freak93
Echipa infoarena
Nu mai tace
*****

Karma: 342
Deconectat Deconectat

Mesaje: 819



Vezi Profilul
« Răspunde #7 : Noiembrie 27, 2010, 22:59:52 »

Nu stiu daca chiar vrei sa afli solutia cu invers modulari. Asta e cea care am implementat-o in timpul olimpiadei si am luat 80 nu 100.
Cred totusi ca se poate obtine si 100 daca e optimizata asa ca hai sa-ti explic:

Descompui numarul Q in factori primi Q=p1^q1 * p2^q2 * ..... *pk^qk

Orice numar val[ i ] din sir poate fi impartit in xval[ i ] si yval[ i ] astfel incat xval[ i ] * yval[ i ] = val[ i ] si xval[ i ] are factori primi numai din multimea {p1,p2,....,pk} si yval[ i ] factori primi care nu apartin aceastei multimi.

Daca notam cu P produsul val[1] * val[2] * .... * val[n], cu xP produsul xval[1] * xval[2] * ... * xval[n] si tot la fel yP din yval[1] s.a.m.d,  atunci P = xP * yP

Pentru a putea calcula prod[ i ] se observa ca in loc sa calculam P/val[ i ] putem calcula (xP/xval[ i ]) * (yP/yval[ i ]) (modulo Q).

yp si yval[ i ] necontinand factori primi comuni cu Q sunt prime cu Q si deci putem aplica invers modular pe ele. Calculam inversul modular a lui yval[ i ] si il inmultim cu yP. Asa obtinem o parte din prod[ i ].

Pentru a obtine a xP/xval[ i ] putem putem face o precalculare. Observam ca k (numarul de factori primi din descompunerae lui Q) e relativ mic <=20. Aflam pentru fiecare valoare la ce putere se afla in xP(sa o notam cu zk). Asta se face la prima parcurgere a sirului cand se calculeaza si yP. Observam ca p1^z1 * p2^z2 * ... * pk^zk = xP

Dupa ce aflam aceste valori se poate calcula o matrice calc in care calc[ i ][ j ] reprezinta pi^(zi-j). j<=30 (evident modulo Q).

Avand aceste valori calculate putem afla pentru orice xval[ i ] cat face xP/xval[ i ]. Il descompunem pe xval[ i ]= p1 ^ q1' * p2 ^q2' * ... * pk^qk'. Atunci xP/xval[ i ] va fi egal cu produsul elementelor calc[ i ][ qi' ] pentru i de la 1 la k.

Asa se formeaza solutia:
1) La prima parcurgere se descompune fiecare val in xval si yval si se calculeaza zi (pentru i de la k) si yP;
2) Se calculeaza matricea calc. (asta se face usor prin exponentiere rapida pana la zi-30( pentru i de la 1 la k) si inmultind cu pi pana se ajunge la zi cu exponentul.
2) La a doua parcurgere se descompun iar numerele val in xval si yval(pentru ca evident ele nu se pot mentine in memorie). Se calculeaza xP/xval[ i ] dupa procedeul descris mai sus si yP/yval[ i ] folosind invers modulare. Se inmultesc cele 2 astfel obtinandu-se prod[ i ] care se XOR-eaza cu raspunsul .

Later Edit: Complexitatea Worst Case este O(n*log2(val_max) ) unde val_max in situatia de fata este 1.000.000.000. Pe cazul mediu se comporta mult mai bine, un O(n) cu constanta 8 din cate cred, voi incerca sa calculez si sa pun aici.
« Ultima modificare: Noiembrie 30, 2010, 00:06:38 de către Budau Adrian » Memorat
S7012MY
Nu mai tace
*****

Karma: 26
Deconectat Deconectat

Mesaje: 648



Vezi Profilul
« Răspunde #8 : Noiembrie 29, 2010, 09:26:10 »

Ms mult  Very Happy
Memorat
dushmi
Nu mai tace
*****

Karma: 130
Deconectat Deconectat

Mesaje: 472



Vezi Profilul
« Răspunde #9 : Aprilie 14, 2011, 12:01:08 »

A reusit cineva sa ia 100 pe acesta problema cu divide et impera??? Eu am tot incercat diverse optimizari si nu reusesc sa intru in timp pe ultimele 5 teste Confused
Memorat
klamathix
Echipa infoarena
Nu mai tace
*****

Karma: 733
Deconectat Deconectat

Mesaje: 1.216



Vezi Profilul
« Răspunde #10 : Aprilie 14, 2011, 14:00:03 »

Ma indoiesc ca se poate, am incercat si eu de cateva ori. Mergea foarte greu pe teste mari si l-am rugat intr-o seara pe Dragos Rotaru, cel care a pus problema in arhiva, sa mareasca pentru cateva minute limita la 20 de secunde ca sa vad de curiozitate cat i-ar lua executia pe infoarena.
http://infoarena.ro/job_detail/493324

Deci slabe sanse. Eu pana la urma am bagat varianta in sqrt(n) memorie Smile
« Ultima modificare: Aprilie 14, 2011, 14:05:34 de către Mihai Calancea » Memorat
dushmi
Nu mai tace
*****

Karma: 130
Deconectat Deconectat

Mesaje: 472



Vezi Profilul
« Răspunde #11 : Aprilie 14, 2011, 14:12:35 »

Multumesc mult pt raspunsul rapid... Ma mir cu de ia asa de mult timp... Mie imi intra in < 6 secunde pe toate testele de la ONI ( Celeron la 1.8 GHz si 2 GB de RAM)...

O sa incerc si solutia de sqrt(n) Very Happy
Memorat
SpiderMan
Nu mai tace
*****

Karma: -463
Deconectat Deconectat

Mesaje: 937



Vezi Profilul
« Răspunde #12 : Iulie 04, 2011, 21:17:49 »

Vai doamne ce horror e problema asta, am reusit sa iau 100 cu divide et impera  Yahoo! http://infoarena.ro/job_detail/601094.
Memorat
danalex97
Vorbaret
****

Karma: 54
Deconectat Deconectat

Mesaje: 192



Vezi Profilul
« Răspunde #13 : Martie 05, 2012, 19:02:09 »

Poate cineva sa imi explice solutia cu invers modular sau sa imi trimita/posteze sursa ? Am facut si eu una cu invers modular , insa intra doar pt primele 5 teste  Eh?

Multumesc anticipat  Ok
Memorat
geniucos
Vorbaret
****

Karma: 21
Deconectat Deconectat

Mesaje: 199



Vezi Profilul
« Răspunde #14 : Mai 16, 2012, 22:31:23 »

Imi poate spune si mie cineva ce e gresit in sursa mea de nu prinde nici un test?Pe primul exemplu am urmarit cu watch-ul si imi merge ca la carte.
Cod:
void divide(unsigned long long i,unsigned long long j,unsigned long long ai,unsigned long long bi,unsigned long long prod)
{
if(i==j)
{
nr++;
if(nr==1) s=prod;
else s=s^prod;
}
else
{
unsigned long long c1,c2,c3,c4,ai1,bi1,a1,b1,p1,p2;
unsigned long long c5;
ai1=ai;
bi1=bi;
unsigned long long mij=(i+j)/2;
unsigned long long k;
a1=ai;
b1=bi;
k=i;
p1=max(1,((k%p)^((a1+1)&(b1+1))%p)%p);
for(k=i+1;k<=mij;k++)
{
a1=((ai+p-1)^(bi+1))%p;
b1=((ai+p-1)|(bi+1))%p;
p1=(1LL*p1*max(1,((k%p)^((a1+1)&(b1+1))%p)%p))%q;
ai=a1;
bi=b1;
}
/////////////////
a1=((ai+p-1)^(bi+1))%p;
b1=((ai+p-1)|(bi+1))%p;
divide(mij+1,j,a1,b1,(prod*p1)%q);
ai=a1;
bi=b1;
k=mij+1;
p2=max(1,((k%p)^((a1+1)&(b1+1))%p)%p);
for(k=mij+1;k<=j;k++)
{
a1=((ai+p-1)^(bi+1))%p;
b1=((ai+p-1)|(bi+1));
p2=(1LL*p2*max(1,((k%p)^((a1+1)&(b1+1))%p)%p))%q;
ai=a1;
bi=b1;
}
divide(i,mij,ai1,bi1,(1LL*prod*p2)%q);
}
}

Foloseste tag-ul code cand postezi cod pe forum
« Ultima modificare: Mai 16, 2012, 23:08:13 de către Mihai-Alexandru Dusmanu » Memorat
Pagini: [1]   În sus
  Imprimă  
 
Schimbă forumul:  

Powered by SMF 1.1.19 | SMF © 2006-2013, Simple Machines