原題:數組
校門外有不少樹,有蘋果樹,香蕉樹,有會扔石頭的,有能夠吃掉補充體力的……
現在學校決定在某個時刻在某一段種上一種樹,保證任一時刻不會出現兩段相同種類的樹,現有兩個操做:
K=1,K=1,讀入l、r表示在區間[l,r]中種上一種樹,每次操做種的樹的種類都不一樣
K=2,讀入l,r表示詢問l~r之間能見到多少種樹
(l,r>0)spa
輸入樣例:code
5 4
1 1 3
2 2 5
1 2 4
2 3 5blog
樣例輸出:排序
1
2博客
曾經,校門外的樹是幾行的暴力染色io
而後,校門外的樹是長長的線段樹class
後來啊,校門外的樹是幾行的樹狀數組效率
判斷詢問的區間與以前多少個已知區間有交集程序
若是將以前的已知區間雙關鍵字排序
再作二分查找
很快就能獲得有交集的區間數量
那麼如今只有兩個事情要辦:
一、排序,要讓已知的區間始終是有序的
二、查找,以logn的效率迅速找有交集的已知區間
能夠用來聯繫線段樹,也能做爲樹狀數組的嘗試
步驟(原來在寫線段樹的,寫到一半忽然發現樹狀數組可解,因而直接刪代碼寫樹狀數組):
1:若是當前根不爲空:獲得一個區間信息,從根開始,若是該區間比根小,則把左子節點當成根作下一次操做的根,比根大則把右子節點做爲下一次操做的根
2:若是當前根爲空:愉快地將該區間信息放在根位置上
3:返回第一步
個人程序:
1 #include <stdio.h> 2 int h[50010],t[50010]; 3 int n,k; 4 void add(int a[],int k) 5 { 6 while(k<=n){ 7 a[k]++; 8 k+=k&(-k); 9 } 10 } 11 int search(int a[],int k) 12 { 13 int tot=0; 14 while(k){ 15 tot+=a[k]; 16 k-=k&(-k); 17 } 18 return tot; 19 } 20 int main() 21 { 22 23 scanf("%d%d",&n,&k); 24 for(int i=1;i<=k;i++) 25 { 26 int a,b,c; 27 scanf("%d%d%d",&a,&b,&c); 28 if(a==1){ 29 add(h,b); 30 add(t,c); 31 } 32 else printf("%d\n",search(h,c)-search(t,b-1)); 33 } 34 }
PS:博客園第一文