pku2528 Mayor's Posters

http://hi.baidu.com/raulliubo/blog/item/db8b8a527fb6070a0df3e372.html

今天一下午光做这道题了。。这题很明显的离散化 + 线段树。RE了半天,郁闷了我半天,为什么呢,为什么呢。一直不知道为什么。

最后抱着试一试的想法把数组开的大了些。。结果。。。TMD AC了。。我再次无语了。

my ugly code:

type
    lisan = record
        w, num : longint;
        l : boolean;
    end;
   
var
    sum, cases, c, n, i, j, tot, ans : longint;
    len : array[0 .. 21000] of lisan;
    w : array[0 .. 10000, 1 .. 2] of longint;
    key, left, right : array[0 .. 100000] of longint;
    v : array[0 .. 10000] of boolean;
   
procedure qsort(l, r : longint);
var
    i, j, mid : longint;
    temp : lisan;
begin
    i := l; j := r; mid := len[(i + j) shr 1].w;
    repeat
        while len[i].w < mid do inc(i);
        while len[j].w > mid do dec(j);
        if i <= j then begin
            temp := len[i]; len[i] := len[j]; len[j] := temp;
            inc(i); dec(j);
        end;
    until i > j;
    if i < r then qsort(i, r);
    if l < j then qsort(l, j);
end;

procedure buildtree(now, l, r : longint);
begin
    if now > sum then sum := now;
    left[now] := l;
    right[now] := r;
    key[now] := 0;
    if r - l > 1 then begin
        buildtree(now * 2, l, (l + r) shr 1);
        buildtree(now * 2 + 1, (l + r) shr 1, r);
    end;
end;

procedure insert(now, l, r, co : longint);
var
    mid : longint;
begin
    if now > sum then exit;
    if key[now] <> co then begin
        if (left[now] = l) and (right[now] = r) then begin
            key[now] := co;
            exit;
        end;
        mid := (left[now] + right[now]) shr 1;
        if key[now] > 0 then begin
            key[now * 2] := key[now];
            key[now * 2 + 1] := key[now];
            key[now] := -1;
        end;
        if mid <= l then
            insert(now * 2 + 1, l, r, co)
        else
        if mid >= r then
            insert(now * 2, l, r, co)
        else
        begin
            insert(now * 2, l, mid, co);
            insert(now * 2 + 1, mid, r, co);
        end;
    end;
end;

procedure count(now : longint);
begin
    if key[now] > 0 then
        v[key[now]] := true
    else begin
        if now * 2 <= sum then
            count(now * 2);
        if now * 2 + 1 <= sum then
            count(now * 2 + 1);
        end;
end;

begin
readln(c);
for cases := 1 to c do begin   
    readln(n);
    fillchar(len, sizeof(len), 0);
    fillchar(v, sizeof(v), 0);
    fillchar(key, sizeof(key), 0);
    fillchar(left, sizeof(left), 0);
    fillchar(right, sizeof(right), 0);
    j := 1;
    for i := 1 to n do begin
        readln(w[i, 1], w[i, 2]);
        len[j].w := w[i, 1] - 1;
        len[j].num := i;
        len[j].l := true;
        inc(j);
        len[j].w := w[i, 2];
        len[j].num := i;
        len[j].l := false;
        inc(j);
    end;
    qsort(1, j);
    if len[1].l then
        w[len[1].num, 1] := 0
    else
        w[len[1].num, 2] := 0;
    tot := 0;
    for i := 2 to j do begin
        if (len[i].w <> len[i-1].w) then inc(tot);
        if len[i].l then
            w[len[i].num, 1] := tot
        else
            w[len[i].num, 2] := tot;
    end;
    sum := 0;
    buildtree(1, 0, tot);
    for i := 1 to n do
        insert(1, w[i, 1], w[i, 2], i);
    count(1);
    ans := 0;
    for i := 1 to n do
        if v[i] then inc(ans);
    writeln(ans);
end;
end.

 

posted @ 2009-01-04 12:24  jesonpeng  阅读(208)  评论(0编辑  收藏  举报