2012-12-21 18:42:06Morris

[UVA][塊狀表] 12003 - Array Transformer


  Array Transformer 

Write a program to transform an array A[1], A[2],..., A[n] according to m instructions. Each instruction (L, R, v, p) means: First, calculate how many numbers from A[L] to A[R] (inclusive) are strictly less than v, call this answer k. Then, change the value of A[p] to u*k/(R - L + 1), here we use integer division (i.e. ignoring fractional part).

Input 

The first line of input contains three integer n, m, u ( 1$ le$n$ le$300, 000, 1$ le$m$ le$50, 000, 1$ le$u$ le$1, 000, 000, 000). Each of the next n lines contains an integer A[i] ( 1$ le$A[i]$ le$u). Each of the next m lines contains an instruction consisting of four integers L, R, v, p ( 1$ le$L$ le$R$ le$n, 1$ le$v$ le$u, 1$ le$p$ le$n).

Output 

Print n lines, one for each integer, the final array.

Sample Input 

10 1 11
1
2
3
4
5
6
7
8
9
10
2 8 6 10

Sample Output 

1
2
3
4
5
6
7
8
9
6


Explanation: There is only one instruction: L = 2, R = 8, v = 6, p = 10. There are 4 numbers (2,3,4,5) less than 6, so k = 4. The new number in A[10] is 11*4/(8 - 2 + 1) = 44/7 = 6.



O(sqrt(n)) 於任何操作。
噁心煩人的塊狀表 ...


#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define SIZE 550
struct ele {
    int v, idx;
};
ele piece[SIZE][SIZE];
int A[SIZE*SIZE];
bool cmp(ele a, ele b) {
    return a.v < b.v;
}
int query(int l, int r, int v) {
    static int cnt, lp, rp, m, tl, tr;
    cnt = 0;
    tl = l;
    tr = r;
    while(l%SIZE && l <= r) {
        if(A[l] < v)    cnt++;
        l++;
    }
    while((r+1)%SIZE && l <= r) {
        if(A[r] < v)    cnt++;
        r--;
    }
    if(l > r)   return cnt;
    lp = l/SIZE, rp = r/SIZE, v--;
    while(lp <= rp) {
        l = 0, r = SIZE-1;
        while(l < r) {
            m = (l+r+1)>>1;
            if(piece[lp][m].v <= v)
                l = m;
            else
                r = m-1;
        }
        if(piece[lp][l].v > v)    l--;
        cnt += l+1;
        lp++;
    }
    return cnt;
}
int main() {
    int n, m, u, l, r, v, p;
    int i, j, x, y;
    while(scanf("%d %d %d", &n, &m, &u) == 3) {
        for(i = 0, j = (n-1)/SIZE; i < SIZE; i++)
            piece[j][i].v = 2147483647, piece[j][i].idx = -1;
        for(i = 0; i < n; i++) {
            scanf("%d", &A[i]);
            piece[i/SIZE][i%SIZE].v = A[i];
            piece[i/SIZE][i%SIZE].idx = i;
        }
        for(i = (n-1)/SIZE; i >= 0; i--)
            sort(piece[i], piece[i]+SIZE, cmp);
        /*for(i = 0; i <= psize; i++, puts(""))
            for(j = 0; j < pidx[i]; j++)
                printf("%d ", piece[i][j].v);*/
        while(m--) {
            scanf("%d %d %d %d", &l, &r, &v, &p);
            l--, r--, p--;
            x = query(l, r, v);
            y = (int)((long long)x*u/(r-l+1));
            x = p/SIZE;
            for(i = 0; piece[x][i].idx != p; i++);
            for(; i < SIZE; i++) {
                piece[x][i].v = piece[x][i+1].v;
                piece[x][i].idx = piece[x][i+1].idx;
            }
            for(i = SIZE-2; i >= 0 && piece[x][i].v > y; i--) {
                piece[x][i+1].v = piece[x][i].v;
                piece[x][i+1].idx = piece[x][i].idx;
            }
            piece[x][i+1].v = y;
            piece[x][i+1].idx = p;
            A[p] = y;
        }
        for(i = 0; i < n; i++)
            printf("%d\n", A[i]);
    }
    return 0;
}