Cod sursa(job #2)

Utilizator dominoMircea Pasoi domino Data 6 noiembrie 2006 02:07:22
Problema Algola Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <stdio.h>
#include <stdlib.h>

#define MAX_N 50005
#define MAX_K 25
#define MOD 30103
#define FIN "albinuta.in"
#define FOUT "albinuta.out"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int N, K, M, U[MAX_N], P[MAX_N], cnt, len, size, Res;
int *T1[MAX_K], *T2[MAX_K], S[MAX_K], L, R, X;

int gcd(int a, int b)
{
    return !b ? a : gcd(b, a%b);
}

void update(int idx, int n, int l, int r)
{
    int m =(l+r)>>1;

    if (L <= l && r <= R)
    {
        T1[idx][n] = (T1[idx][n] + X) % MOD;
        T2[idx][n] = (T2[idx][n] + X*(r-l+1)) % MOD;
        return;
    }
    if (L <= m) update(idx, n<<1, l, m);
    if (R > m) update(idx, (n<<1)|1, m+1, r);
    T2[idx][n] = (T1[idx][n]*(r-l+1) + T2[idx][n<<1] + T2[idx][(n<<1)|1]) % MOD;
}

int query(int idx, int n, int l, int r)
{
    int m = (l+r)>>1, t = 0;

    if (L <= l && r <= R) return T2[idx][n];
    if (L <= m) t += query(idx, n<<1, l, m);
    if (R > m) t += query(idx, (n<<1)|1, m+1, r);
    t += T1[idx][n]*(MIN(R,r)-MAX(L,l)+1);
    return t%MOD;
}

int main(void)
{
    int i, j, a, b, c;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    scanf("%d %d %d", &N, &K, &M);
    for (i = a = 0; i < N; i++)
    {
        if (U[i]) continue;
        for (a++, b = 0, j = i; !U[j]; j = (j+K)%N)
            U[j] = a, P[j] = b++;
    }

    cnt = gcd(N, K); len = N/cnt;
    for (size = 1; size < (len<<1); size<<=1);
    for (i = 0; i < cnt; i++)
    {
        T1[i] = (int *) calloc(size+1, sizeof(int));
        T2[i] = (int *) calloc(size+1, sizeof(int));
    }

    for (; M > 0; M--)
    {
        scanf("%d %d %d", &a, &b, &c);
        a--; b++; i = U[a]-1; j = P[a]; 
        if (c)
        {
            S[i] = (S[i] + (b/len)*c) % MOD;
            b %= len;
            if (!b) continue;
            if (j+b <= len)
            {
                L = j, R = j+b-1, X = c;
                update(i, 1, 0, len-1);
            }
            else
            {
                L = j, R = len-1, X = c;
                update(i, 1, 0, len-1);
                L = 0, R = (j+b-1)%len, X = c;
                update(i, 1, 0, len-1);
            }
        }
        else
        {
            L = 0, R = len-1;
            Res = (S[i]*len+query(i, 1, 0, len-1)) % MOD;
            Res = (Res*(b/len)) % MOD;
            b %= len;
            if (!b) { printf("%d\n", Res); continue; }
            Res = (Res+b*S[i]) % MOD;
            if (j+b <= len)
            {
                L = j, R = j+b-1;
                Res += query(i, 1, 0, len-1);
                if (Res >= MOD) Res -= MOD;
            }
            else
            {
                L = j, R = len-1;
                Res += query(i, 1, 0, len-1);
                if (Res >= MOD) Res -= MOD;
                L = 0, R = (j+b-1)%len;
                Res += query(i, 1, 0, len-1);
                if (Res >= MOD) Res -= MOD;
            }       
            printf("%d\n", Res);
        }
    }

    return 0;
}