codeforces 878D

Thinking questions (after reading the explanations himself drew a long time to get to know ...)

Meaning of the questions: given k 12 ) Creatures, each creature has n 105 ) A characteristic, then q 105 ) Operations, before the two can optionally generate a new biological organism (characteristic of max / min values ​​of the biological properties of these two), a query may be a property of a biological before each operation.

Ideas: new biological characteristics of each are generated based on the initial k Creatures, each creature can be generated so that subsequent before use k A series of biological max / min operation represented. Here we define a new attribute (to each creature 2k A bits), in order to indirectly represented before k After the results of a series of operations creatures. Initially, for 1 ~ k The first i Biological terms, the 0 ~ 2k1 The figures for the first i Bits to 1 Digital set 1 The rest is 0 . Then subsequent to these organisms max / min operation or to convert it / them with the operation of this new property . For example, the operator max (first i Biological, first j Bio) is to get 0 ~ 2k1 The figures for the first i Bits to 1 Or the first j Bits to 1 Digital set 1 The rest is 0 . (At this time for new biological terms, 0 ~ 2k1 1 which is set to the number increases); and vice versa. Then ask bio x A feature Y Operation, we turn first k This feature creatures from high to low enumeration Y (Corresponding to the front k Whether the new property creatures number), then look to the current enumeration of organisms are organisms x The new attributes, including (that is, see x A bit of new properties whether 1 )。

#include <cstdio>
#include <algorithm>
#include <bitset>

using namespace std;
const int maxn = 100050;

int a[15][maxn], rk[maxn][15];
bitset<4096> bt[maxn];

int cmp_id;
bool cmp(const int x, const int y) {
    return a[x][cmp_id] < a[y][cmp_id];
}

int main() {
    int n, k, q;
    while(scanf("%d%d%d",&n,&k,&q) == 3) {
        for(int i=1; i<=k; i++)
            for(int j=1; j<=n; j++) {
                scanf("%d",&a[i][j]);
                rk[j][i] = i;
            }
        for(int j=1; j<=n; j++) {
            cmp_id = j;
            sort(rk[j]+1, rk[j]+k+1, cmp);
        }
        for(int i=1; i<=k; i++)
            for(int j=0; j<(1<<k); j++) {
                if(j&(1<<(i-1))) bt[i][j] = 1;
                else bt[i][j] = 0;
            }
        int tot = k;
        while(q --) {
            int op, x, y;
            scanf("%d%d%d",&op,&x,&y);
            if(op == 1)
                bt[++tot] = bt[x] | bt[y];
            else if(op == 2)
                bt[++tot] = bt[x] & bt[y];
            else {
                int id = k+1, cur = 0;
                while(bt[x][cur] == 0) {
                    id --;
                    cur |= 1<<(rk[y][id]-1);
                }
                printf("%d\n",a[rk[y][id]][y]);
            }
            /*printf("tot:%d\n",tot);
            for(int j=0; j<(1<<k); j++)
                printf("%d ",(int)bt[tot][j]);
            puts("");*/
        }
    }
    return 0;
}
Published 40 original articles · won praise 44 · views 90000 +

Guess you like

Origin blog.csdn.net/Site1997/article/details/78636845