[BZOJ2298] [HAOI2011]problem a

来源:互联网 发布:锁扣地板 知乎 编辑:程序博客网 时间:2024/04/30 20:05

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=2298

题目大意

naibi,可能排名相同
询问最少有几个人说谎

题解

通过每个人说的话,我们可以得到这个人所在的区间,即这段人的排名相同
那么如果两个区间有交集且不吻合,那么一定有一个人说谎
吻合的话,吻合段数大于区间长度也有人说谎
这样,我们将问题转化为一些有权的线段,询问最大权(没说谎的人数)
dp[i]:[1,i]
dp[i]=dp[i1]
i线
dp[r]=max{dp[i],dp[l1]+v[线]}

uses math;const    maxn=100000;var    x:array[0..maxn,1..3]of longint;    w:array[0..2*maxn,1..3]of longint;    dp,s:array[0..maxn]of longint;    i,j,k:longint;    n,m,a,b,tt,len,cnt:longint;procedure sort(l,r:longint);var a,b,c,i,j:longint;begin    i:=l; j:=r; a:=x[(l+r)div 2,2]; b:=x[(l+r)div 2,1];    repeat        while (x[i,2]<a)or((x[i,2]=a)and(x[i,1]<b)) do inc(i);        while (x[j,2]>a)or((x[j,2]=a)and(x[j,1]>b)) do dec(j);                if not(i>j) then        begin            c:=x[i,1]; x[i,1]:=x[j,1]; x[j,1]:=c;            c:=x[i,2]; x[i,2]:=x[j,2]; x[j,2]:=c;            inc(i); dec(j);        end;    until i>j;    if l<j then sort(l,j);    if i<r then sort(i,r);end;procedure init(a,b,c:longint);begin    w[len,1]:=b; w[len,2]:=c;    if w[a,3]=0 then w[a,3]:=len else w[w[a,1],3]:=len;    w[a,1]:=len; inc(len); end;begin    readln(n); cnt:=n; m:=0;    for i:=1 to n do        begin            readln(b,a);            inc(a); b:=n-b;            if a>b then continue;            inc(m); x[m,1]:=a; x[m,2]:=b;        end;    n:=m; sort(1,n); {x[i,2],x[i,1]}    x[n+1,1]:=cnt+1; x[n+1,2]:=cnt+1;    tt:=0; m:=0;    for i:=1 to n+1 do        if (x[i,1]<>x[i-1,1])or(x[i,2]<>x[i-1,2])        then begin x[m,1]:=x[i-1,1]; x[m,2]:=x[i-1,2]; x[m,3]:=min(tt,x[m,2]-x[m,1]+1); tt:=1; inc(m); end        else inc(tt);    dec(m); len:=cnt+1;    for i:=1 to m do        init(x[i,2],x[i,1],x[i,3]);    for i:=1 to cnt do        begin            tt:=w[i,3]; dp[i]:=dp[i-1];            while tt<>0 do                begin                    dp[i]:=max(dp[i],dp[w[tt,1]-1]+w[tt,2]);                    tt:=w[tt,3];                end;        end;    writeln(cnt-dp[cnt]);end.
0 0
原创粉丝点击