LL powmod(LL a, LL b, LL p){
    LL res = 1;
    while(b){
        if(b & 1) res = multmod(res, a, p);
        a = multmod(a, a, p), b >>= 1;
    }
    return res;
}
Example #2
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);
}
Example #3
0
void advance_state(int k)

/******************************************************************************/
/*
  Purpose:

    ADVANCE_STATE advances the state of the current generator.

  Discussion:

    This procedure advances the state of the current generator by 2^K 
    values and resets the initial seed to that value.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    30 March 2013

  Author:

    Original Pascal version by Pierre L'Ecuyer, Serge Cote.
    C version by John Burkardt.

  Reference:

    Pierre LEcuyer, Serge Cote,
    Implementing a Random Number Package with Splitting Facilities,
    ACM Transactions on Mathematical Software,
    Volume 17, Number 1, March 1991, pages 98-111.

  Parameters:

    Input, int K, indicates that the generator is to be 
    advanced by 2^K values.
    0 <= K.
*/
{
    const int a1 = 40014;
    const int a2 = 40692;
    int b1;
    int b2;
    int cg1;
    int cg2;
    int g;
    int i;
    const int m1 = 2147483563;
    const int m2 = 2147483399;

    if (k < 0) {
        fprintf(stderr, "\n");
        fprintf(stderr, "ADVANCE_STATE - Fatal error!\n");
        fprintf(stderr, "  Input exponent K is out of bounds.\n");
        exit(1);
    }
/*
  Check whether the package must be initialized.
*/
    if (!initialized_get()) {
        initialize();
    }
/*
  Get the current generator index.
*/
    g = cgn_get();

    b1 = a1;
    b2 = a2;

    for (i = 1; i <= k; k++) {
        b1 = multmod(b1, b1, m1);
        b2 = multmod(b2, b2, m2);
    }

    cg_get(g, &cg1, &cg2);
    cg1 = multmod(b1, cg1, m1);
    cg2 = multmod(b2, cg2, m2);
    cg_set(g, cg1, cg2);

    return;
}
Example #4
0
void init_generator(int t)

/******************************************************************************/
/*
  Purpose:

    INIT_GENERATOR sets the state of generator G to initial, last or new seed.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    01 April 2013

  Author:

    Original Pascal version by Pierre L'Ecuyer, Serge Cote.
    C version by John Burkardt.

  Reference:

    Pierre LEcuyer, Serge Cote,
    Implementing a Random Number Package with Splitting Facilities,
    ACM Transactions on Mathematical Software,
    Volume 17, Number 1, March 1991, pages 98-111.

  Parameters:

    Input, int T, the seed type:
    0, use the seed chosen at initialization time.
    1, use the last seed.
    2, use a new seed set 2^30 values away.
*/
{
    const int a1_w = 1033780774;
    const int a2_w = 1494757890;
    int cg1;
    int cg2;
    int g;
    int ig1;
    int ig2;
    int lg1;
    int lg2;
    const int m1 = 2147483563;
    const int m2 = 2147483399;
/*
  Check whether the package must be initialized.
*/
    if (!initialized_get()) {
        initialize();
    }
/*
  Get the current generator index.
*/
    g = cgn_get();
/*
  0: restore the initial seed.
*/
    if (t == 0) {
        ig_get(g, &ig1, &ig2);
        lg1 = ig1;
        lg2 = ig2;
        lg_set(g, lg1, lg2);
    }
/*
  1: restore the last seed.
*/
    else if (t == 1) {
        lg_get(g, &lg1, &lg2);
    }
/*
  2: advance to a new seed.
*/
    else if (t == 2) {
        lg_get(g, &lg1, &lg2);
        lg1 = multmod(a1_w, lg1, m1);
        lg2 = multmod(a2_w, lg2, m2);
        lg_set(g, lg1, lg2);
    } else {
        fprintf(stderr, "\n");
        fprintf(stderr, "INIT_GENERATOR - Fatal error!\n");
        fprintf(stderr, "  Input parameter T out of bounds.\n");
        exit(1);
    }
/*
  Store the new seed.
*/
    cg1 = lg1;
    cg2 = lg2;
    cg_set(g, cg1, cg2);

    return;
}
Example #5
0
void set_initial_seed(int ig1, int ig2)

/******************************************************************************/
/*
  Purpose:

    SET_INITIAL_SEED resets the initial seed and state for all generators.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    28 March 2013

  Author:

    Original Pascal version by Pierre L'Ecuyer, Serge Cote.
    C version by John Burkardt.

  Reference:

    Pierre LEcuyer, Serge Cote,
    Implementing a Random Number Package with Splitting Facilities,
    ACM Transactions on Mathematical Software,
    Volume 17, Number 1, March 1991, pages 98-111.

  Parameters:

    Input, int IG1, IG2, the initial seed values 
    for the first generator.
    1 <= IG1 < 2147483563
    1 <= IG2 < 2147483399
*/
{
    const int a1_vw = 2082007225;
    const int a2_vw = 784306273;
    int g;
    const int g_max = 32;
    //int i;
    const int m1 = 2147483563;
    const int m2 = 2147483399;
    int t;

    if (ig1 < 1 || m1 <= ig1) {
        fprintf(stderr, "\n");
        fprintf(stderr, "SET_INITIAL_SEED - Fatal error!\n");
        fprintf(stderr, "  Input parameter IG1 out of bounds.\n");
        exit(1);
    }

    if (ig2 < 1 || m2 <= ig2) {
        fprintf(stderr, "\n");
        fprintf(stderr, "SET_INITIAL_SEED - Fatal error!\n");
        fprintf(stderr, "  Input parameter IG2 out of bounds.\n");
        exit(1);
    }
/*
  Because INITIALIZE calls SET_INITIAL_SEED, it's not easy to correct
  the error that arises if SET_INITIAL_SEED is called before INITIALIZE.
  So don't bother trying.
*/
    if (!initialized_get()) {
        printf("\n");
        printf("SET_INITIAL_SEED - Fatal error!\n");
        printf("  The RNGLIB package has not been initialized.\n");
        exit(1);
    }
/*
  Set the initial seed, then initialize the first generator.
*/
    g = 0;
    cgn_set(g);

    ig_set(g, ig1, ig2);

    t = 0;
    init_generator(t);
/*
  Now do similar operations for the other generators.
*/
    for (g = 1; g < g_max; g++) {
        cgn_set(g);
        ig1 = multmod(a1_vw, ig1, m1);
        ig2 = multmod(a2_vw, ig2, m2);
        ig_set(g, ig1, ig2);
        init_generator(t);
    }
/*
  Now choose the first generator.
*/
    g = 0;
    cgn_set(g);

    return;
}