Advertisement
Guest User

1440.cpp

a guest
Jun 14th, 2018
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.95 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <vector>
  3. #include <string>
  4. #include <functional>
  5. #include <cassert>
  6. #include <cstdlib>
  7.  
  8. inline int prev(int p, int n) {
  9.     return p == 0 ? n-1 : p-1;
  10. }
  11.  
  12. inline int next(int p, int n) {
  13.     return p == n-1 ? 0 : p+1;
  14. }
  15.  
  16. std::string solve(const std::vector<int>& a) {
  17.     const int n = a.size();
  18.    
  19.     // Считаем префикс-суммы:
  20.     std::vector<int> pref{0};
  21.     for (int i = 0; (int)pref.size() <= 2*n; i = next(i, n)) {
  22.         pref.push_back(pref.back() + a[i]);
  23.     }
  24.     int sum = pref[n];
  25.    
  26.     // Обрабатываем особый случай:
  27.     if (sum == 0) {
  28.         return std::string(n, '1');
  29.     }
  30.    
  31.     // Функция поиска разбиения массива на number отрезков с одинаковой суммой. Возвращает true, если такое разбиение существует.
  32.     std::function<bool(int)> is_possible = [&](int number) {
  33.         if (number == 1) {
  34.             return true;
  35.         }
  36.        
  37.         const int need = sum / number; // Нужная сумма каждого отрезка
  38.         assert(need * number == sum);
  39.        
  40.         // Находим отрезок [0, r] такой, что sum[0,r] <= need, sum[0,r+1] > need
  41.         int l = 0, r = -1, curr = 0;
  42.         while (curr + a[next(r,n)] <= need) {
  43.             curr += a[next(r,n)];
  44.             r = next(r,n);
  45.         }
  46.        
  47.         // Сдвигаем отрезок [l, r], получая все возможные отрезки, на которых сумма равна need и которые содержат нулевой элемент:
  48.         while (r >= 0) {
  49.             // Сдвигаем левую границу пока не накопили нужную сумму:
  50.             while (curr + a[prev(l,n)] <= need) {
  51.                 curr += a[prev(l,n)];
  52.                 l = prev(l,n);
  53.             }
  54.             if (curr == need) {
  55.                 // Пробуем построить еще number-1 отрезков, сумма на которых равна need:
  56.                 int low = r+1, prev = r, count = number-1;
  57.                 while (count > 0) {
  58.                     if (pref[low+1] - pref[low] > need) {
  59.                         break;
  60.                     }
  61.                     // [low, high)
  62.                     int high = l == 0 ? n : l;
  63.                     while (high-low > 1) {
  64.                         int mid = (low + high) / 2;
  65.                         if (pref[mid+1] - pref[prev+1] > need) {
  66.                             high = mid;
  67.                         } else {
  68.                             low = mid;
  69.                         }
  70.                     }
  71.                     if (pref[low+1]-pref[prev+1] == need) {
  72.                         --count;
  73.                         prev = low++;
  74.                     } else {
  75.                         break;
  76.                     }
  77.                 }
  78.                 if (count == 0) {
  79.                     return true;
  80.                 }
  81.             }
  82.             // Сдвигаем правую границу:
  83.             curr -= a[r];
  84.             --r;
  85.         }
  86.         return false;
  87.     };
  88.      
  89.     std::string answ(n, '0');
  90.     // Перебираем все делители суммы элементов массива:
  91.     for (int i = 1; i * i <= sum; ++i) {
  92.         const int j = sum / i;
  93.         if (j * i == sum) {
  94.             if (i <= n) {
  95.                 assert(answ[i-1] == '0');
  96.                 answ[i-1] += is_possible(i);
  97.             }
  98.             if (j <= n && j != i) {
  99.                 assert(answ[j-1] == '0');
  100.                 answ[j-1] += is_possible(j);
  101.             }
  102.         }
  103.     }
  104.     assert(answ[0] == '1');
  105.     return answ;
  106. }
  107.  
  108. int main() {
  109.     int n;
  110.     scanf("%d", &n);
  111.     std::vector<int> a(n);
  112.     for (auto& it : a) {
  113.         scanf("%d", &it);
  114.     }
  115.     printf("%s\n", solve(a).c_str());
  116.     return 0;
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement