HDU6703 array(權值線段樹)

考慮建權值線段樹,那麼線段樹存的值就是它的座標,考慮到答案一定存在且最大值爲n+1n+1,可以多加一個點n+1n+1
對於操作1 (1,x)(1,x),直接單點修改位置s[x]s[x]n+1n+1(s[x]爲初始位置x的值)
對於操作2 (2,r,x)(2,r,x),要查詢區間[x,n+1][x,n+1]內第一個大於rr的位置,考慮建一棵維護最大值的線段樹,比賽時候第一次寫這種問題,當時的思路是,查詢時先訪問左子樹,假如左子樹不行才訪問右子樹,但是這個時候的複雜度是log(n)log(n)log(n)*log(n),然後開始yy各種剪枝,最後有用的剪枝是當查詢的區間包含現在的區間時,可以直接判斷符不符合情況,這樣可以把多的log(n)log(n)變成常數

int query(int p,int l,int r,int x,int y,int tmp)//query(1,1,n+1,x,n+1,r)
	{
		if(l == r)//查詢到葉子節點
		{
			if(tr[p] > tmp)
			{
				return l;
			}
			else
			{
				return -1;
			}
		}
		if(x <= l && r <= y)//區間包含於查詢區間
		{
			if(tr[p] <= tmp)
			{
				return -1;
			}
		}
		int mid = (l+r)/2;
		if(y <= mid)
		{
			return query(p*2,l,mid,x,y,tmp);
		}
		if(x >= mid + 1)
		{
			return query(p*2+1,mid+1,r,x,y,tmp);
		}

		int judge = query(p*2,l,mid,x,y,tmp);//先判斷左子樹

		if(judge != -1)
		{
			return judge;
		}

		return query(p*2+1,mid+1,r,x,y,tmp);

	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章