Ejemplo n.º 1
0
int main()
{
    
    vector<i64> vn2;
    i64 nmax = 123456787654321;
    vn2.push_back(nmax % nmod);
    i64 n = nmax;
    int count = 0;
    while(n){
        n/=2;        
        vn2.push_back(n % nmod);
        vn2[count] -= vn2[count+1];
        ++count;
    }
    i64 sum = 0;
    for(int i = 0; i<(int)vn2.size(); ++i){
        for(int j = i; j<(int)vn2.size();++j){
            for(int k=j; k<(int)vn2.size();++k){
                i64 mult = 6;
                if(i==j && j==k)
                    mult = 1;
                else if(i==j||j==k||i==k){
                    mult = 3;
                }
                if((i^j^k)==0){
                    mult = multmod(mult, vn2[i], nmod);
                    mult = multmod(mult, vn2[j], nmod);
                    mult = multmod(mult, vn2[k], nmod);
                    printf("%d %d %d %lld %lld %lld %lld\n", i, j, k, vn2[i], vn2[j], vn2[k], mult);
                    sum = addmod(sum ,mult, nmod);
                }
            }
        }
    }
    i64 nx = nmax%nmod;
    i64 x0 = multmod(nx, nx, nmod);
    x0 = multmod(x0, nx, nmod);
    sum = addmod(x0, -sum, nmod);
    if(sum < 0) sum += nmod;
    printf("%lld\n", sum);
}
Ejemplo n.º 2
0
Archivo: BN.cpp Proyecto: ramyaraju/kg
__int64 mulmod(__int64 a, __int64 b, __int64 n)
{
	__int64 r;
	if(!n) return -1;

	a %= n;
	b %= n;
	if (!b||!a) return 0;
	if (a<0) a += n;
	if (b<0) b += n;

	r = 0;

	while(b)
	{
		if(b&1) r = addmod(r,a,n);
		b>>=1;
		a = addmod(a,a,n);
	}
	return r;
}
Ejemplo n.º 3
0
static int test_anr(UV a, UV n, UV r)
{
  UV* pn;
  UV* res;
  UV i;
  int retval = 1;

  Newz(0, pn, r, UV);
  if (pn == 0)
    croak("Couldn't allocate space for polynomial of degree %lu\n", (unsigned long) r);
  a %= r;
  pn[0] = a;
  pn[1] = 1;
  res = poly_mod_pow(pn, n, r, n);
  res[n % r] = addmod(res[n % r], n - 1, n);
  res[0]     = addmod(res[0],     n - a, n);

  for (i = 0; i < r; i++)
    if (res[i] != 0)
      retval = 0;
  Safefree(res);
  Safefree(pn);
  return retval;
}
Ejemplo n.º 4
0
	/* k = 2 */
	s = *x1;

	w = w3table[2];
	tmp = MULMOD(*x2, w);
	s = addmod(s, tmp, umod);

	w = w3table[1];
	tmp = MULMOD(*x3, w);
	s = addmod(s, tmp, umod);

	*x3 = s;
	*x2 = r2;
	*x1 = r1;
}
#else /* PPRO */
static inline void
ppro_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_uint_t w3table[3],
               mpd_uint_t umod, double *dmod, uint32_t dinvmod[3])
{
	mpd_uint_t r1, r2;
	mpd_uint_t w;
	mpd_uint_t s, tmp;


	/* k = 0 -> w = 1 */
	s = *x1;
	s = addmod(s, *x2, umod);
	s = addmod(s, *x3, umod);

	r1 = s;

	/* k = 1 */
	s = *x1;

	w = w3table[1];
	tmp = ppro_mulmod(*x2, w, dmod, dinvmod);
	s = addmod(s, tmp, umod);

	w = w3table[2];
	tmp = ppro_mulmod(*x3, w, dmod, dinvmod);
	s = addmod(s, tmp, umod);

	r2 = s;

	/* k = 2 */
	s = *x1;

	w = w3table[2];
	tmp = ppro_mulmod(*x2, w, dmod, dinvmod);
	s = addmod(s, tmp, umod);

	w = w3table[1];
	tmp = ppro_mulmod(*x3, w, dmod, dinvmod);
	s = addmod(s, tmp, umod);

	*x3 = s;
	*x2 = r2;
	*x1 = r1;
}
Ejemplo n.º 5
0
static inline void
std_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3,
              mpd_uint_t w3table[3], mpd_uint_t umod)
{
	mpd_uint_t r1, r2;
	mpd_uint_t w;
	mpd_uint_t s, tmp;


	/* k = 0 -> w = 1 */
	s = *x1;
	s = addmod(s, *x2, umod);
	s = addmod(s, *x3, umod);

	r1 = s;

	/* k = 1 */
	s = *x1;

	w = w3table[1];
	tmp = MULMOD(*x2, w);
	s = addmod(s, tmp, umod);

	w = w3table[2];
	tmp = MULMOD(*x3, w);
	s = addmod(s, tmp, umod);

	r2 = s;

	/* k = 2 */
	s = *x1;

	w = w3table[2];
	tmp = MULMOD(*x2, w);
	s = addmod(s, tmp, umod);

	w = w3table[1];
	tmp = MULMOD(*x3, w);
	s = addmod(s, tmp, umod);

	*x3 = s;
	*x2 = r2;
	*x1 = r1;
}
Ejemplo n.º 6
0
/* Fast Number Theoretic Transform, decimation in frequency. */
void
fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams)
{
    mpd_uint_t *wtable = tparams->wtable;
    mpd_uint_t umod;
#ifdef PPRO
    double dmod;
    uint32_t dinvmod[3];
#endif
    mpd_uint_t u0, u1, v0, v1;
    mpd_uint_t w, w0, w1, wstep;
    mpd_size_t m, mhalf;
    mpd_size_t j, r;


    assert(ispower2(n));
    assert(n >= 4);

    SETMODULUS(tparams->modnum);

    /* m == n */
    mhalf = n / 2;
    for (j = 0; j < mhalf; j += 2) {

        w0 = wtable[j];
        w1 = wtable[j+1];

        u0 = a[j];
        v0 = a[j+mhalf];

        u1 = a[j+1];
        v1 = a[j+1+mhalf];

        a[j] = addmod(u0, v0, umod);
        v0 = submod(u0, v0, umod);

        a[j+1] = addmod(u1, v1, umod);
        v1 = submod(u1, v1, umod);

        MULMOD2(&v0, w0, &v1, w1);

        a[j+mhalf] = v0;
        a[j+1+mhalf] = v1;

    }

    wstep = 2;
    for (m = n/2; m >= 2; m>>=1, wstep<<=1) {

        mhalf = m / 2;

        /* j == 0 */
        for (r = 0; r < n; r += 2*m) {

            u0 = a[r];
            v0 = a[r+mhalf];

            u1 = a[m+r];
            v1 = a[m+r+mhalf];

            a[r] = addmod(u0, v0, umod);
            v0 = submod(u0, v0, umod);

            a[m+r] = addmod(u1, v1, umod);
            v1 = submod(u1, v1, umod);

            a[r+mhalf] = v0;
            a[m+r+mhalf] = v1;
        }

        for (j = 1; j < mhalf; j++) {

            w = wtable[j*wstep];

            for (r = 0; r < n; r += 2*m) {

                u0 = a[r+j];
                v0 = a[r+j+mhalf];

                u1 = a[m+r+j];
                v1 = a[m+r+j+mhalf];

                a[r+j] = addmod(u0, v0, umod);
                v0 = submod(u0, v0, umod);

                a[m+r+j] = addmod(u1, v1, umod);
                v1 = submod(u1, v1, umod);

                MULMOD2C(&v0, &v1, w);

                a[r+j+mhalf] = v0;
                a[m+r+j+mhalf] = v1;
            }

        }

    }

    bitreverse_permute(a, n);
}
Ejemplo n.º 7
0
static void poly_mod_sqr(UV* px, UV* res, UV r, UV mod)
{
  UV c, d, s, sum, rindex, maxpx;
  UV degree = r-1;
  int native_sqr = (mod > isqrt(UV_MAX/(2*r))) ? 0 : 1;

  memset(res, 0, r * sizeof(UV)); /* zero out sums */
  /* Discover index of last non-zero value in px */
  for (s = degree; s > 0; s--)
    if (px[s] != 0)
      break;
  maxpx = s;
  /* 1D convolution */
  for (d = 0; d <= 2*degree; d++) {
    UV *pp1, *pp2, *ppend;
    UV s_beg = (d <= degree) ? 0 : d-degree;
    UV s_end = ((d/2) <= maxpx) ? d/2 : maxpx;
    if (s_end < s_beg) continue;
    sum = 0;
    pp1 = px + s_beg;
    pp2 = px + d - s_beg;
    ppend = px + s_end;
    if (native_sqr) {
      while (pp1 < ppend)
        sum += 2 * *pp1++  *  *pp2--;
      /* Special treatment for last point */
      c = px[s_end];
      sum += (s_end*2 == d)  ?  c*c  :  2*c*px[d-s_end];
      rindex = (d < r) ? d : d-r;  /* d % r */
      res[rindex] = (res[rindex] + sum) % mod;
#if defined(HAVE_UINT128)
    } else {
      uint128_t max = ((uint128_t)1 << 127) - 1;
      uint128_t c128, sum128 = 0;

      while (pp1 < ppend) {
        c128 = ((uint128_t)*pp1++)  *  ((uint128_t)*pp2--);
        if (c128 > max) c128 %= mod;
        c128 <<= 1;
        if (c128 > max) c128 %= mod;
        sum128 += c128;
        if (sum128 > max) sum128 %= mod;
      }
      c128 = px[s_end];
      if (s_end*2 == d) {
        c128 *= c128;
      } else {
        c128 *= px[d-s_end];
        if (c128 > max) c128 %= mod;
        c128 <<= 1;
      }
      if (c128 > max) c128 %= mod;
      sum128 += c128;
      if (sum128 > max) sum128 %= mod;
      rindex = (d < r) ? d : d-r;  /* d % r */
      res[rindex] = ((uint128_t)res[rindex] + sum128) % mod;
#else
    } else {
      while (pp1 < ppend) {
        UV p1 = *pp1++;
        UV p2 = *pp2--;
        sum = addmod(sum, mulmod(2, mulmod(p1, p2, mod), mod), mod);
      }
      c = px[s_end];
      if (s_end*2 == d)
        sum = addmod(sum, sqrmod(c, mod), mod);
      else
        sum = addmod(sum, mulmod(2, mulmod(c, px[d-s_end], mod), mod), mod);
      rindex = (d < r) ? d : d-r;  /* d % r */
      res[rindex] = addmod(res[rindex], sum, mod);
#endif
    }
  }