Cod sursa(job #25465)

Utilizator sandyxpSanduleac Dan sandyxp Data 4 martie 2007 12:40:13
Problema Balanta Scor 90
Compilator cpp Status done
Runda preONI 2007, Runda 3, Clasa a 10-a Marime 2.3 kb
#include <cstdio>
#include <cstring>

#define FIN "balanta.in"
#define FOUT "balanta.out"
#define MAXN 34

int V[2][MAXN], // apartin monedele printre care daca e cea naspa, atunci e mai grea/usoara;
    no[2]={0,0}, n, m;

inline void put(int where, int who)
{
    int i;
    for (i=0; where; where >>= 1, ++i)
        if (where & 1) {
            if ( ! (V[i][who>>5] & (1<<(who&0x1f))) )  ++no[i];
            V[i][who>>5] |= 1 << (who & 0x1f);
        }
}

inline void rem(int where, int who)
{
    int i;
    for (i=0; where; where >>= 1, ++i)
        if (where & 1) {
            if ( V[i][who>>5] & (1<<(who&0x1f)) ) --no[i];
            V[i][who>>5] &= ~(1 << (who & 0x1f));
        }
}

void rezolvare()
{
    int i, j, nr, r, A[2][MAXN], x;

    freopen(FIN, "r", stdin);
    freopen(FOUT,"w",stdout);
    scanf("%d %d", &n, &m);

    for (i=1; i<=n; ++i) put(3, i); 

    for (i=0; i<m; ++i)
    {
        scanf("%d", &nr);
        memset(A, 0, sizeof(A));
        for (j=0; j<nr; ++j) { scanf("%d", &x); A[0][x>>5] |= 1 << (x & 0x1f); }
        for (j=0; j<nr; ++j) { scanf("%d", &x); A[1][x>>5] |= 1 << (x & 0x1f); }
        scanf("%d", &r);
        if (r == 0) {
            //for (j=0; j<nr*2; ++j) rem(3, A[0][j]);  // 1-G, 10-U
            for (j=0; j < MAXN; ++j)  V[0][j] &= ~A[0][j], V[1][j] &= ~A[1][j];
        } else {
            //for (j=0; j<nr; ++j) { put(1<<(r-1), A[0][j]); rem(1<<(r&1), A[0][j]); }
            //for (j=0; j<nr; ++j) { put(1<<(r&1), A[1][j]); rem(1<<(r-1), A[1][j]); }
            for (j=0; j < MAXN; ++j)  V[!(r&1)][j] &= A[0][j], V[r&1][j] &= A[1][j];
        }
        for (j=1, no[0]=no[1]=0; j <= n; ++j)
            no[0] += (V[0][j>>5] & (1<<(j&0x1f)))!=0, no[1] += (V[1][j>>5] & (1<<(j&0x1f)))!=0;
    }
    if (no[0] != no[1])
    {
        if (no[0] == 1)
            for (i=1; i<=n; ++i) if (V[0][i>>5]&(1<<(i&0x1f))) { printf("%d\n", i); return; } // mai grea
        if (no[1] == 1)
            for (i=1; i<=n; ++i) if (V[1][i>>5]&(1<<(i&0x1f))) { printf("%d\n", i); return; } // mai usoara
    } else if (no[0] == no[1] && no[0] == 1)
        for (i=1; i<=n; ++i) 
            if ( ( V[1][i>>5]&(1<<(i&0x1f)) ) && ( V[0][i>>5]&(1<<(i&0x1f)) ) ) {
                printf("%d\n", i); return; // nush cum e, da aia e
            }
    printf("0\n");
}

int main()
{
    rezolvare();
    return 0;
}