幾次的省賽,成績都不是很理想。不過這幾次省賽的給我們留下了很多寶貴的經驗: 首先發現的是線段樹,每考必有: 今天我們學習的就是線段樹: 線段樹的功能是: 1、對一段數字進行累加。 2、對數字進行搜尋。 3、將包含在區間int的元素x插入到樹t中。 4、從線段樹中刪除元素x。 5、對線段樹上的資料進行更新。 今天,我們要做的是poj3468: 題目大意:第一行輸入n、m;第二行輸入n個資料;接下來有m行分別輸入字母與幾個資料,如果的 字母是q則輸入l、r,表示查詢下標為l~r的資料總和;字母為c則輸入l,r,c,表示從下標為l到下標為r的資料加上c。 思路:線段樹可以完成對數字的搜尋,並且可以方便的資料進行更新,所以我們採用了線段樹演算法。 方法:
#include#include#includeusing namespace std;
struct pointt[400005];
__int64 map[400005];
void create(int u,int l,int r)
int mid = (t[u].l+t[u].r)>>1;//右移相當於除以2,mid表示的就是區間之間的中點
create(u<<1,l,mid);
create(u<<1|1,mid+1,r);//u為下乙個的節點。
t[u].sum = t[u<<1].sum+t[u<<1|1].sum;
}void updata(int u,int l,int r,__int64 c)
t[u].sum = t[u].sum+(r-l+1)*c;
int mid = (t[u].l+t[u].r)>>1;
if(r<=mid)
updata(u<<1,l,r,c);
else if(l>mid)
updata(u<<1|1,l,r,c);
else }
__int64 query(int u,int l,int r)
int mid = (t[u].l+t[u].r)>>1;
if(r<=mid)
return query(u<<1,l,r);
else if(l>mid)
return query(u<<1|1,l,r);
else
return query(u<<1,l,mid)+query(u<<1|1,mid+1,r);
}int main()
else
//getchar();
} }return 0;
}
這道題,讓我明白了乙個問題,就是當你使用scanf()的時候,會比較省時間,而cin會比較不省時間。做了好久才正確理解了這題的意思,看來我應該多做點線段樹的題目。嘿嘿~明天加油咯~
演算法 線段樹
線段樹的根節點是整段區間,其它結點是由區間不斷二分得到的子區間,其中葉子結點是區間的每個單獨的元素。這裡使用結構體存線段樹。struct tree tree 4 maxn 2 注意陣列大小至少要開到區間長度的四倍大這裡預設我們要求的是區間和,故結點值均為區間和。可以視情況改變結點值的含義。void ...
演算法 線段樹 活動排期衝突問題
今天偶然遇到了乙個有點意思的問題,將它轉化成了題目,有點令人懷念 有一張活動排期表,表上有n組活動的排期。其中,每組活動都會開啟若干次,每個活動都有乙個唯一id和乙個開啟時間a,關閉時間b。同組活動不能在相同時間內開啟兩個及以上。如果同組活動同時開啟,則會產生衝突,活動開啟失敗。問 當前活動表內是否...
ccf除法 線段樹模板
這題的要求是對區間處理,查詢區間和,一看就是線段樹模板題,下面是 includeusing namespace std int pp 100001 struct qp 2000001 void build int l,int r,long long x 建樹函式 int m l r 2 build ...