bzoj1594

首先想到二分答案

然后我们从大往小加区间,如果之前出现了一个区间包含当前区间

那显然不合法,我们可以用并查集了维护

  1 type node=record
  2        x,y,mi,id:longint;
  3      end;
  4
  5 var q:array[0..25010] of node;
  6     a:array[0..25010] of longint;
  7     fa:array[0..1000010] of longint;
  8     l,r,m,n,t,i,ans:longint;
  9
 10 function min(a,b:longint):longint;
 11   begin
 12     if a>b then exit(b) else exit(a);
 13   end;
 14
 15 function max(a,b:longint):longint;
 16   begin
 17     if a>b then exit(a) else exit(b);
 18   end;
 19
 20 procedure swap(var a,b:node);
 21   var c:node;
 22   begin
 23     c:=a;
 24     a:=b;
 25     b:=c;
 26   end;
 27
 28 procedure sort(l,r:longint);
 29   var i,j,x:longint;
 30   begin
 31     i:=l;
 32     j:=r;
 33     x:=q[(l+r) shr 1].mi;
 34     repeat
 35       while x<q[i].mi do inc(i);
 36       while q[j].mi<x do dec(j);
 37       if not(i>j) then
 38       begin
 39         swap(q[i],q[j]);
 40         inc(i);
 41         dec(j);
 42       end;
 43     until i>j;
 44     if l<j then sort(l,j);
 45     if i<r then sort(i,r);
 46   end;
 47
 48 function have(l,r:longint):boolean;
 49   var x:longint;
 50   begin
 51     x:=r;
 52     while x>=l do
 53     begin
 54       if fa[x]=0 then exit(false);
 55       x:=fa[x]-1;
 56     end;
 57     exit(true);
 58   end;
 59
 60 procedure work(l,r:longint);
 61   var x:longint;
 62   begin
 63     x:=r;
 64     while x>=l do
 65     begin
 66       if fa[x]=0 then fa[x]:=l
 67       else begin
 68         x:=fa[x];
 69         if x>=l then fa[x]:=l;
 70       end;
 71       dec(x);
 72     end;
 73   end;
 74
 75 function check(m:longint):boolean;
 76   var s,i,j,x,y,k:longint;
 77   begin
 78     fillchar(fa,sizeof(fa),0);
 79     s:=0;
 80     for i:=1 to t do
 81       if q[i].id<=m then
 82       begin
 83         inc(s);
 84         a[s]:=i;
 85       end;
 86
 87     i:=0;
 88     while i<s do
 89     begin
 90       inc(i);
 91       j:=i+1;
 92       while (j<=s) and (q[a[i]].mi=q[a[j]].mi) do inc(j);
 93       dec(j);
 94       x:=0;
 95       y:=n+1;
 96       for k:=i to j do
 97       begin
 98         x:=max(x,q[a[k]].x);
 99         y:=min(y,q[a[k]].y);
100       end;
101       if x>y then exit(false);
102       if have(x,y) then exit(false);
103       for k:=i to j do
104         work(q[a[k]].x,q[a[k]].y);
105       i:=j;
106     end;
107     exit(true);
108   end;
109
110 begin
111   readln(n,t);
112   for i:=1 to t do
113   begin
114     readln(q[i].x,q[i].y,q[i].mi);
115     q[i].id:=i;
116   end;
117   sort(1,t);
118   l:=1;
119   r:=t-1;
120   if check(t) then writeln(0)
121   else begin
122     ans:=t;
123     while l<=r do
124     begin
125       m:=(l+r) shr 1;
126       if not check(m) then
127       begin
128         ans:=m;
129         r:=m-1;
130       end
131       else l:=m+1;
132     end;
133     writeln(ans);
134   end;
135 end.

时间: 2024-08-27 06:00:58

bzoj1594的相关文章

bzoj1594 Pku3764 The xor-longest Path

题目链接 先求每个点到根的异或和 然后就要找出两个点,使dis[a]^dis[b]最大 注意异或的性质,我们可以用trie树,沿着与当前数字每位的相反方向走 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath

[BZOJ1594] [Usaco2008 Jan]猜数游戏(二分 + 并查集)

传送门 题中重要信息,每堆草的数量都不一样. 可以思考一下,什么情况下才会出现矛盾. 1.如果两个区间的最小值一样,但是这两个区间没有交集,那么就出现矛盾. 2.如果两个区间的最小值一样,并且这两个区间有交集,那么这个最小值一定在交集中,但是如果这个交集被某个最小值较大的区间,或是一些最小值较大的区间的并集包含,那么也是矛盾的. 可以二分答案,将这些区间按照最小值从大到小排序,然后可以用线段树维护,也可以用并查集来搞. 下面是用并查集来搞的. 每到一个区间,可以将[l,r]中的f变成r+1,如果

[bzoj1594]猜数游戏

主要是怎么处理矛盾 矛盾的条件有$2$种: 第一种是当把所有相等的$a$都全部找到后,他们并没有全联通,所以矛盾,因为没有两个是相同的 第二种是在2组$(l,r,a)$,$(l1,r1,a1)$中,$a<a1$并且$(l,r)$ 包含在$(l1,r1)$,矛盾 所以怎么去维护,第一种直接暴力查询,第二种我们可以从大到小排序$minn$,去在线段树中维护并集操作,看一看是否被覆盖即可 此答案具有单调性,所以可以通过二分优化 #include<iostream> #include<cs