Advertisement
a53

abc_Bunget_macelarit

a53
Dec 27th, 2017
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.45 KB | None | 0 0
  1. #include <cstdio>
  2. #define BAZA 1000000
  3. #define Nmax 100000
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8. int a,b;
  9. scanf("%d %d",&a,&b); /// Citesc datele de intrare a si b
  10. int c=a*b;
  11. int copie_c=c,repr_binar_a_lui_c[22]; /// repr_binar_a_lui_c va memora reprezentarea binara a lui c=axb
  12. while(copie_c!=0)
  13. repr_binar_a_lui_c[++repr_binar_a_lui_c[0]]=copie_c%2,copie_c=copie_c/2;
  14. int i,j,doi_la_a_minus_1=1;
  15. for(i=1;i<=a;++i) /// Calculez 2^a
  16. doi_la_a_minus_1=doi_la_a_minus_1*2;
  17. --doi_la_a_minus_1; /// Scad 1 si obtin 2^a-1
  18. int d; /// Memoreaza cel mai mic divizor al lui 2^a-1
  19. long long p1;
  20. for(i=2;i<=doi_la_a_minus_1;++i) /// Calculez primul divizor d al lui 2^a-1
  21. {
  22. p1=1;
  23. for(j=repr_binar_a_lui_c[0];j>=1;--j)
  24. if(repr_binar_a_lui_c[j]==0 )
  25. p1=(p1*p1)%i;
  26. else
  27. p1=(p1*p1*2)%i;
  28. if(p1==1)
  29. {
  30. d=i;
  31. break;
  32. }
  33. }
  34. int r=c%15; /// 2^15=32768
  35. int doi_la_r=1 ;
  36. for(i=1;i<=r;++i) /// Calculez 2^r
  37. doi_la_r=doi_la_r*2;
  38. int n=c/15;
  39. long long A[Nmax]; /// Numarul A=2^(axb)-1
  40. A[0]=1; /// Memoreaza numarul de cifre ale lui A in baza BAZA
  41. A[1]=1; /// La inceput A=1
  42. long long t,t1; /// Transportul t
  43. for(i=1;i<=n;++i) /// Calculez A=2^c (pentru ca inmultesc cu 32768, iar c=n*15)
  44. {
  45. t=0;
  46. for(j=1;j<=A[0];++j) /// ? Calculez produsele intermediare, impreuna cu suma intermediara
  47. {
  48. t1=(A[j]*32768+t)%BAZA;
  49. t=(A[j]*32768+t)/BAZA;
  50. A[j]=t1 ;
  51. }
  52. if(t>0)
  53. A[++A[0]]=t;
  54. }
  55. t=0;
  56. for(j=1;j<=A[0];++j) /// ? Corectez sumele intermediare
  57. {
  58. t1=(A[j]*doi_la_r+t)%BAZA;
  59. t=(A[j]*doi_la_r+t)/BAZA;
  60. A[j]=t1;
  61. }
  62. if(t>0) /// Daca ultimul transport e mai mare decat 0, il "adaug" la rezultat
  63. A[++A[0]]=t;
  64. i=1;
  65. while(A[i]==0)
  66. ++i;
  67. --A[i];
  68. t=0;
  69. for(i=A[0];i>=1;--i) /// Calculez A/d (divizorul propriu maxim)
  70. {
  71. t1=(t*BAZA+A[i])/d;
  72. t=(t*BAZA+A[i])%d;
  73. A[i]=t1;
  74. }
  75. while(A[A[0]]==0)
  76. --A[0];
  77. printf("%ld",A[A[0]]); /// Afisez rezultatul (prima valoare fara zerouri nesemnificative)
  78. for(i=A[0]-1;i>=1;--i)
  79. printf("%06ld",A[i]); /// iar restul valorilor le completez cu zerouri in fata
  80. return 0;
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement