#ifndef LOCAL_H
 #define LOCAL_H

/////////////////////////////////////////////
// ローカルで計算できる関数
/////////////////////////////////////////////

_ PrefixSum(_ v)
{
  if (_party >  2) return NULL;
  int n = len(v);
  _ ans = _dup(v);
  _ sum = _slice(v, 0, 1);
  _setpublic(sum, 0, 0);
  for (int i=0; i<n; i++) {
    _addshare(sum, 0, v, i);
    _setshare(ans, i, sum, 0);
  }
  _free(sum);
  return ans;
}

_ SuffixSum(_ v)
{
  if (_party >  2) return NULL;
  int n = len(v);
  _ ans = _dup(v);
  _ sum = _slice(v, 0, 1);
  _setpublic(sum, 0, 0);
  for (int i=n-1; i>=0; i--) {
    _addshare(sum, 0, v, i);
    _setshare(ans, i, sum, 0);
  }
  _free(sum);
  return ans;
}

_ Diff(_ v, share_t z)
{
  if (_party >  2) return NULL;
  int n = len(v);
  _ ans = _dup(v);
  _ prev = _slice(v, 0, 1);
  _setpublic(prev, 0, z);
  for (int i=0; i<n; i++) {
    _setshare(ans, i, v, i);
    _subshare(ans, i, prev, 0);
    _setshare(prev, 0, v, i);
  }
  _free(prev);
  return ans;
}

_ rank1(_ v)
{
  if (_party >  2) return NULL;
  int n = len(v);
  _ ans = _dup(v);
  _ sum = _slice(v, 0, 1);
  _setpublic(sum, 0, 0);
  for (int i=0; i<n; i++) {
    _addshare(sum, 0, v, i);
    _setshare(ans, i, sum, 0);
  }
  _free(sum);
  return ans;
}

_ rank0(_ v)
{
  if (_party >  2) return NULL;
  int n = len(v);
  _ ans = _dup(v);
  _ sum = _slice(v, 0, 1);
  _setpublic(sum, 0, 0);
  for (int i=0; i<n; i++) {
    _addpublic(sum, 0, 1);
    _subshare(sum, 0, v, i);
    _setshare(ans, i, sum, 0);
  }
  _free(sum);
  return ans;
}

_ sum(_ v)
{
  if (_party >  2) return NULL;
  int n = len(v);
  _ ans = _slice(v, 0, 1);
  for (int i=1; i<n; i++) {
    _addshare(ans, 0, v, i);
  }
  return ans;
}


void addall(_ a, _ b)
{
  if (_party >  2) return;
  int n = len(a);
  for (int i=0; i<n; i++) {
    _addshare(a, i, b, 0);
  }
}

//////////////////////////////////////////////////////////////////
// x の連続する l 個の和を求める
//////////////////////////////////////////////////////////////////
share_array extended_sum(int l, share_array x) {
    int n = len(x);
    share_t q = order(x);
    if (n % l != 0) {
        printf("extended_sum    n = %d, l = %d, n %% l = %d\n", n, l, n % l);
        exit(1);
    }

    share_array ans = share_const(l, 0, q);
    for (int i = 0; i < n / l; ++i) {
        for (int j = 0; j < l; ++j) {
            share_addshare(ans, j, x, i * l + j);
        }
    }

    return ans;
}


#endif
