Cod sursa(job #86627)

Utilizator goguGogu Marian gogu Data 25 septembrie 2007 02:12:15
Problema Curcubeu Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <cstdio>
#include <string.h>
#define MaxN 1000100
#define MaxR (3*MaxN)
#define LIM 32

unsigned n, a, b, c, st, fn;
int cul[MaxR], A[MaxN], first[MaxN], last[MaxN], color[MaxN];
char full[MaxR];

inline void update(unsigned p, unsigned u, unsigned r)
{
     if (u-p < LIM){
        if (full[r])
           for (unsigned i=p; i<=u; i++) A[i] = cul[r];     
        full[r] = 0;
        if (p<st) p=st;
        if (u>fn) u=fn;
        while (p <= u) A[p++] = c;
        return;
     }
     if (st<=p && u<=fn){
        full[r] = 1;
        cul[r] = c;
        return;
     }
     if (full[r]){
        full[2*r] = full[2*r+1] = 1;
        cul[2*r] = cul[2*r+1] = cul[r];
        full[r] = 0;
     }
     unsigned mij = (p+u)/2;
     if (st<=mij) update(p, mij, 2*r);
     if (fn > mij)update(mij+1, u, 2*r+1);
}

inline void scrie(unsigned k)
{
     char lin[20], *s;
     s=lin+19; s[0]='\n';
     unsigned lung = 1;
     do {
        unsigned cat=k/10;
        s--;
        s[0]=k-cat*10+'0';
        k=cat;
        lung++;
     } while (k);
     fwrite(s, 1, lung, stdout);
}

void afis(unsigned p, unsigned u, unsigned r)
{
     if (u-p < LIM){
        if (full[r])
           for (unsigned i=p; i<=u; i++) A[i] = cul[r];     
        while (p <= u) scrie(A[p++]);
        return;
     }
     if (full[r]){
        while (p <= u) ++p, scrie(cul[r]);
        return;
     }
     unsigned mij = (p+u)/2;
     afis(p, mij, 2*r);
     afis(mij+1, u, 2*r+1);
}

int main()
{
    freopen("curcubeu.in", "r", stdin);
    freopen("curcubeu.out", "w", stdout);
    scanf("%u %u %u %u", &n, &a, &b, &c);
    full[1] = 1;
    for (unsigned i=2; i<=n; i++){
        if (a<b) st=a, fn=b; else st=b, fn=a;
        first[i] = st;
        last[i] = fn;
        color[i] = c;
        a = ((unsigned long long) a * i) % n;
        b = ((unsigned long long) b * i) % n;
        c = ((unsigned long long) c * i) % n;
    }
    for (unsigned i=2; i<=n; i++){
        int ok=1;
        for (unsigned j=1; j<LIM; j++)
            if (first[i+j]<=first[i] && last[i]<=last[i+j]) ok=0;
        st = first[i];
        fn = last[i];
        c = color[i];
        if (!ok) continue;
        update(1, n-1, 1);
    }
    afis(1, n-1, 1);
    return 0;
}