HDU1540 Tunnel Warfare(線段樹+set)

題目連接: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

明天補上~

相關文章
相關標籤/搜索