題目連接:HDU 1540php
題意:ios
題意是一條線上的點,D x是破壞這個點,Q x是表示查詢以x所在的最長的連續的點的個數,R是恢復上一次破壞的點。數組
最近在作線段樹的專題,碰巧作到了這題,本身沒有想出思路,百度出來的題解也沒有認真看。。spa
此次回來又想了一下,查詢最長連續點的個數,也就是查詢其左右兩邊最近的破壞點的座標,而後求差就是所求個數了。code
直接將破壞的數儲存在數組二分不就出來結果了。寫出來發現陽曆不對,數組並不有序,不能二分。而有序的插入,或者再排序都太浪費時間。排序
因而咱們神奇的set出現了~用set的有序性以及刪除增長節點的O(log(n))效率,加上lowbound,很容易模擬了出來。get
寒假要去實現set ,map!string
【源代碼】it
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<set> using namespace std; const int maxn = 50000+ 10; int arr[maxn]; set<int>st; int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ int po = 0; char ch; int num; st.clear(); while(m--){ scanf(" %c",&ch); if(ch == 'D'){ scanf("%d",&num); arr[po++] = num; //儲存刪除的節點 st.insert(num); } else if(ch =='Q'){ scanf("%d",&num); set<int>::iterator l = lower_bound(st.begin(),st.end(),num); int ll; if(l == st.end()){ //若是沒有找到比當前大的節點,返回的迭代器爲尾元素的下一個迭代器,也就是.end() if(l != st.begin()){ --l; ll = *l; ++l; printf("%d\n",n-ll); } else{ printf("%d\n",n); } } else{ if(*l == num){ //找到相同節點直接輸出0; printf("%d\n",0); } else{ if(l != st.begin()){ --l; ll = *l; ++l; printf("%d\n",*l-ll-1); } else{ printf("%d\n",*l-1); } } } } else{ //cout<<arr[po-1]<<endl; st.erase(arr[--po]); //R,重建對應刪除set中的對應元素; } } } return 0; }
【線段樹】io
明天補上~