Advertisement
dmkozyrev

idempotents

Mar 29th, 2015
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <stack>
  5. using namespace std;
  6. bool diophant(long long a, long long b, long long c, long long &x, long long &y);
  7.  
  8. int main()
  9. {
  10.         long long n;
  11.         cout << "Input N: ";
  12. //     long long n = 1, p = 1;
  13. //        while (p != 0) // Ввод n по множителям
  14. //        {
  15. //                n *= p;
  16. //                cin >> p;
  17. //        }
  18.         cin >> n; //Ввод n целиком
  19.         long long m = n;
  20. //Формирование вектора v из взаимнопростых множителей числа n:
  21.         vector < long long > v;
  22.         int c = 0; //Количество взаимнопростых множителей n
  23.         for (long long i = 2; i <= n; ++i)
  24.                 if (n % i == 0)
  25.                 {
  26.                         c++;
  27.                         v.push_back(i);
  28.                         n /= i;
  29.                         while (n % i == 0)
  30.                         {
  31.                                 n /= i;
  32.                                 v.back() *= i;
  33.                         }
  34.                 }
  35. //Вывод на экран разложения n на взаимнопростые множители:
  36.         n = m;
  37.         cout << n << " = " << v.front();
  38.         for (int i = 1; i < c; ++i)
  39.                 cout << "*" << v.at(i);
  40.         cout << endl << "Idempotents: ";
  41. //Двоичный перебор всех вариантов представления n как n = a*b,
  42. //где НОД(a, b) = 1. При этом  исключаем повторы
  43.         long long limit = pow(2, c - 1), a, b, x, y, count = 0;
  44.         for (long long i = 1; i < limit; ++i)
  45.         {
  46.                 m = i;
  47.                 a = b = 1;
  48.                 for (long long j = 0; j < c; ++j)
  49.                 {
  50.                         if (m % 2 == 1)
  51.                         {
  52.                                 a *= v.at(j);
  53.                         }
  54.                         else
  55.                         {
  56.                                 b *= v.at(j);
  57.                         }
  58.                         m /= 2;
  59.                 }
  60.                 //Решаем составленное диофантово уранение ax + by = 1
  61.                 diophant(a, b, 1, x, y);
  62.                 x *= a; // ax - идемпотент в кольце вычетов Zn
  63.                 //Выбираем x именно из интервала [0 .. n-1]
  64.                 while (x < 0) x += n;
  65.                 while (x >= n) x -= n;
  66.                 //Выбираем парный ему идемпотент 1-x
  67.                 y = n + 1 - x;
  68.                 //Увеличиваем счетчик идемпотентов
  69.                 count += 2;
  70.                 //Выводим найденную пару идемпотентов
  71.                 cout << x << " " << y << " ";
  72.         }
  73.        //Выводим количество идемпотентов:
  74.        cout << endl << "Count indempotents = " << count;
  75. }
  76.  
  77. bool diophant(long long a, long long b, long long c, long long &x, long long &y)
  78. {
  79.         stack < long long >q;
  80.         long long r;
  81.         while (a % b != 0)
  82.         {
  83.                 r = a % b;
  84.                 q.push(a / b);
  85.                 a = b;
  86.                 b = r;
  87.         }
  88.         if (b != 1)
  89.         {
  90.                 return false;
  91.         }
  92.         else
  93.         {
  94.                 long long temp;
  95.                 x = 1;
  96.                 y = q.top();
  97.                 q.pop();
  98.                 while (!q.empty())
  99.                 {
  100.                         temp = x;
  101.                         x = -y;
  102.                         y = -temp - q.top() * y;
  103.                         q.pop();
  104.                 }
  105.                 x *= c;
  106.                 y *= -c;
  107.                 return true;
  108.         }
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement