lyk在玩猜數字遊戲。
總共有n個互不相同的正整數,lyk每次猜一段區間的最小值。形如[li,ri]這段區間的數字的最小值一定等於xi。
我們總能構造出一種方案使得lyk滿意。直到…… lyk自己猜的就是矛盾的!
例如lyk猜[1,3]的最小值是2,[1,4]的最小值是3,這顯然就是矛盾的。
你需要告訴lyk,它第幾次猜數字開始就已經矛盾了。
第一行兩個數n和t,表示有n個數字,lyk猜了t次。
接下來t行,每行三個數分別表示li,ri和xi。
輸出乙個數表示第幾次開始出現矛盾,如果一直沒出現矛盾輸出t+1。
20 4
1 10 7
5 19 7
3 12 8
1 20 1
3資料範圍
對於50%的資料n<=8,t<=10。
對於80%的資料n<=1000,t<=1000。
對於100%的資料1<=n,t<=1000000,1<=li<=ri<=n,1<=xi<=n(但並不保證一開始的所有數都是1~n的)
hint
建議使用讀入優化
inline int read()
這道題我們先考慮矛盾的情況
我們不難發現有以下兩種情況是矛盾的
1.當乙個區間覆蓋了另乙個區間且大的區間的x值比另乙個區間的x值小的時候是矛盾的
2.當兩個區間的x值相同時,如果這兩個區間沒有交集,這也是矛盾的
知道了矛盾的情況後
我們可以二分矛盾的句子的位置
將前k個句子按x值從大到小排個序,然後我們列舉,判斷當前區間的x值和前乙個區間的x值是否相同
如果相同,就判斷一下有沒有交集
如果不相同,我們可以維護乙個線段樹,將交集的區間覆蓋為1,查詢並集的區間是否被覆蓋為1,當然我們也可以用並查集來維護,我是用並查集來做的,但還是感覺線段樹應該好懂一些(雖然**長了些)
1 #include2view code#define n 1000005
3using
namespace
std;
4int
n,t,cnt;
5int
fa[n];
6struct
nodea[n],b[n];
9bool cmp(node x,node y)
10int find(int x)
11bool check(int
x)26 lmin=lmax=b[i].l;
27 rmin=rmax=b[i].r;
28 } else35}
36 f1=find(lmax);
37if (f1>rmin) return
true;38
return
false;39
}40intmain() else l=mid+1;52
}53 printf("
%d\n
",ans);
54return0;
55 }
紅綠 線段樹分治, 並查集
對 1,q to t 1,q tot 1,q t ot 進行線段樹分治,將每個 綠綠 的 影響區間分為 log q tot log q tot logq t ot個區間散布在線段樹節點中,其中 qto tq tot qt o t 為詢問的總數 然後對線段樹dfs dfsdf s,合併祖先鏈的和當前節...
線段樹 樹狀陣列 並查集
利用線段樹十分方便的處理區間,線段樹是一棵完美的二叉樹,樹上的每乙個節點都維護乙個區間,根維護的是整個區間,線段樹通常用來計算區間內資料的和或者是修改某處的值。對區間的操作可以再o logn 的時間內完成。下面我們通過 實現線段樹的構建,修改,區間求和。include include 線段樹 def...
poj1456 並查集or線段樹
本來做並查集專題看到的題目,但是卻是用線段樹a掉的,感覺這題用線段樹做挺水的。先將物品按價值降序排序,然後依次查詢,每個物品的最後期限,就相當於給了線段樹查詢範圍,在1 d範圍內找還有沒有空餘的點,有的話則占用,更新線段樹,單點更新,感覺比較簡單。如果用並查集的話,題目將用過的天作為乙個集合,排序之...