询问
Description
有一個長度為 ?n? n 的正整數序列,序列中元素兩兩不同且都在 [1,109] [ 1 , 10 9 ] 中。
你不知道這個序列是什么。
現在有 ?Q? Q 個詢問 l,r l , r ,每次詢問序列中區間 [l,r] [ l , r ] 的最小值,有一個人回答了這 ?Q? Q 個問題。
但是他太不靠譜,回答可能會自相矛盾。
于是我們要求出一個最小的 ?p? p ,回答的 ?p? p 個詢問后出現了答案自相矛盾的情況。
如果所有的 ?Q? Q 個答案是不互相矛盾的,就輸出 0 0 。
Input
第一行兩個整數 n,Q n,Q。
接下來 ?Q? Q 行,第 ?i? i 行三個整數 ?li,ri,ansi l i , r i , a n s i ,表示第 ?i? i 個詢問 [li,ri] [ l i , r i ] ,回答的答案為 ?ansi a n s i 。
output
按照題目要求輸出一行一個整數。
Sample Input
20 4
1 10 7
5 19 7
3 12 8
11 15 12
Sample Output
3
Data Constraint
?n≤106,m≤25000,1≤ansi≤109 n ≤ 10 6 , m ≤ 25000 , 1 ≤ a n s i ≤ 10 9
Solution
考慮二分答案,接下來判斷前mid個詢問是否矛盾。
把所有詢問按照答案從大到小排序,把答案相同的那些詢問放在一起,求出區
間交及區間并,如果區間交為空說明序列中有重復數字,直接無解;否則我們看
看區間交是否全被覆蓋,如果全被覆蓋顯然之前的區間答案錯誤產生矛盾,如
果沒全被覆蓋我們就把區間并(由于區間交不為空區間并顯然是一段連續區間)
進行覆蓋。
正確性在于如果有 l1≤l2≤r2≤l1 l 1 ≤ l 2 ≤ r 2 ≤ l 1 ,那么顯然有 ans2≥ans1 a n s 2 ≥ a n s 1 ,而如果答案小
的區間全被覆蓋就相當于 ans2<ans1 a n s 2 < a n s 1 。這就產生了矛盾。
那么我們可以用線段樹或并查集的做法,下面就講講并查集。
如果我們將要覆蓋 [l,r] [ l , r ] ,那么我們就要使l~r合并到r+1去,所以當 fai≠i f a i ≠ i
時就說明該區域已被覆蓋,并且當 ?fai=faj? f a i = f a j 時說明i,j被同一區域覆蓋。易得最多只合并 ?n? n 次。
Code
var l,r,mid,fax,fay,i,n,t:longint;g,f:array[1..2] of longint;a,b:array[0..30000,1..3] of longint;fa:array[1..1000005] of longint; function get(x:longint):longint; beginif fa[x]=x then exit(x);fa[x]:=get(fa[x]);exit(fa[x]); end; procedure qsort(x,y:longint); var i,j:longint;k:int64; begini:=x;j:=y;k:=b[(i+j) div 2,3];repeatwhile b[i,3]>k do inc(i);while b[j,3]<k do dec(j);if i<=j then beginb[0]:=b[i];b[i]:=b[j];b[j]:=b[0];inc(i);dec(j);end;until i>j;if i<y then qsort(i,y);if j>x then qsort(x,j); end; function min(x,y:longint):longint; begin if x<y then exit(x);exit(y);end; function max(x,y:longint):longint; begin if x>y then exit(x);exit(y);end; function pan(x:longint):boolean; beginfor i:=1 to x do b[i]:=a[i];for i:=1 to n+1 do fa[i]:=i;qsort(1,x);f[1]:=b[1,1];f[2]:=b[1,2];g[1]:=b[1,1];g[2]:=b[1,2];b[x+1,3]:=-1;for i:=2 to x+1 do beginif b[i,3]=b[i-1,3] then beginif (b[i,1]>f[2]) or (b[i,2]<f[1]) then exit(false) elsef[1]:=max(f[1],b[i,1]);f[2]:=min(f[2],b[i,2]);g[1]:=min(g[1],b[i,1]);g[2]:=max(g[2],b[i,2]);continue;end else beginfax:=get(f[1]);fay:=get(f[2]+1);if fax=fay then exit(false);fax:=get(g[1]);fay:=get(g[2]+1);while fax<>fay do beginfa[fax]:=fax+1;fax:=get(fax+1);end;f[1]:=b[i,1];f[2]:=b[i,2];g[1]:=b[i,1];g[2]:=b[i,2];end;end;exit(true); end; begin assign(input,'bales.in');reset(input); assign(output,'bales.out');rewrite(output);readln(n,t);for i:=1 to t doreadln(a[i,1],a[i,2],a[i,3]);l:=1;r:=t;while l<r do beginmid:=(l+r) div 2;if pan(mid) then l:=mid+1 else r:=mid;end;if (l=t) and (pan(l)) then writeln(0) else writeln(l); close(input); close(output); end.總結
- 上一篇: 计算机专业技术人员最高什么级,事业单位技
- 下一篇: 淘宝升华:脱胎换骨的巨人