bzoj 1067 特判

  这道题的大题思路就是模拟

  假设给定的年份是x,y,首先分为4个大的情况,分别是

  x的信息已知,y的信息已知

  x的信息已知,y的信息未知

  x的信息未知,y的情况已知

  x的信息未知,y的情况未知

  然后对于每一种情况可以根据x到y区间是否存在空位,最大值是否唯一,以及x,y,区间最大值的关系来判定。

  所以对于区间的问题的合并与处理我们用线段树来存就行了。

  反思:开始对情况的优先级判断不清,没有整理好思路就开始写。最后发现线段树的合并函数写错了。

/**************************************************************
    Problem: 1067
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:580 ms
    Memory:5304 kb
****************************************************************/
 
//By BLADEVIL
type
    rec                     =record
        left, right         :longint;
        max                 :longint;
        flag, flag2         :boolean;
        pred, succ          :longint;
    end;
 
var
    n, m                    :longint;
    a, b                    :array[0..50010] of longint;
    t                       :array[0..200010] of rec;
     
function getmax(a,b:longint):longint;
begin
    if a>b then exit(a) else exit(b);
end;
     
function combine(a,b:rec):rec;
begin
    with combine do
    begin
        max:=getmax(a.max,b.max);
        pred:=a.pred;
        succ:=b.succ;
        if a.succ=b.pred-1 then flag:=true else flag:=false;
        flag:=flag and a.flag and b.flag;
         
        if a.max=b.max then flag2:=false else flag2:=true;
        if max=a.max then flag2:=flag2 and a.flag2;
        if max=b.max then flag2:=flag2 and b.flag2;
        left:=a.left;
        right:=b.right;
    end;
end;
     
procedure build(x,l,r:longint);
var
    mid                     :longint;
begin
    t[x].left:=l; t[x].right:=r;
    if l=r then
    begin
        with t[x] do
        begin
            pred:=a[l];
            succ:=a[l];
            flag2:=true;
            max:=b[l];
            flag:=true;
        end;
        exit;
    end;
    with t[x] do mid:=(left+right)>>1;
    build(x<<1,l,mid); build(x<<1+1,mid+1,r);
    t[x]:=combine(t[x<<1],t[x<<1+1]);
end;    
     
procedure init;
var
    i                       :longint;
begin
    read(n);
    for i:=1 to n do read(a[i],b[i]);
    a[0]:=-1;
    build(1,1,n);
end;
 
function getadress(x:longint):longint;
var
    l, r, mid               :longint;
    ans                     :longint;
begin
    l:=1; r:=n;
    ans:=0;
    while l<=r do
    begin
        mid:=(l+r)>>1;
        if a[mid]<=x then
        begin
            ans:=mid;
            l:=mid+1;
        end else r:=mid-1;
    end;
    exit(ans);
end;
 
function ask(x,l,r:longint):rec;
var
    mid                     :longint;
begin
    if (t[x].left=l) and (t[x].right=r) then
        exit(t[x]);
    with t[x] do mid:=(left+right)>>1;
    if mid<l then exit(ask(x<<1+1,l,r)) else
    if mid>=r then exit(ask(x<<1,l,r)) else
        exit(combine(ask(x<<1,l,mid),ask(x<<1+1,mid+1,r)));
end;
 
procedure main;
var
    i                       :longint;
    x, y                    :longint;
    u, v                    :longint;
    query                   :rec;
     
begin
    read(m);
    for i:=1 to m do
    begin
        read(x,y);
        if x>y then
        begin
            writeln('false');
            continue;
        end;
        if x=y then
        begin
            writeln('true');
            continue;
        end;
        u:=getadress(x);
        v:=getadress(y);
        if (a[u]=x) and (a[v]=y) then
        begin
            if b[v]>b[u] then
            begin
                writeln('false');
                continue;
            end;
            query:=ask(1,u+1,v);
            if not query.flag2 then
            begin
                writeln('false');
                continue;
            end;
            if query.max<>b[v] then
            begin
                writeln('false');
                continue;
            end;
            query:=ask(1,u,v);
            if not query.flag then
            begin
                writeln('maybe');
                continue;
            end else
            begin
                writeln('true');
                continue;
            end;
        end else
        if (a[u]<>x) and (a[v]<>y) then
        begin
            writeln('maybe');
            continue;
        end else
        if (a[u]=x) and (a[v]<>y) then
        begin
            if u=v then
            begin
                writeln('maybe');
                continue;
            end;
            query:=ask(1,u+1,v);
            if query.max>=b[u] then
            begin
                writeln('false');
                continue;
            end else
            begin
                writeln('maybe');
                continue;
            end;
        end else
        if (a[u]<>x) and (a[v]=y) then
        begin
            if u=v then
            begin
                writeln('maybe');
                continue;
            end;
            query:=ask(1,u+1,v);
            if not query.flag2 then
            begin
                writeln('false');
                continue;
            end;
            if query.max<>b[v] then
            begin
                writeln('false');
                continue;
            end else
            begin
                writeln('maybe');
                continue;
            end;
        end;
    end;
end;
 
begin
    init;
    main;
end.
 

 

posted on 2014-01-22 19:27  BLADEVIL  阅读(216)  评论(0编辑  收藏  举报