1. 程式人生 > 實用技巧 >Just a Hook(線段樹) HDU - 1698

Just a Hook(線段樹) HDU - 1698

題意:給你一個長度為N節的金屬鉤子,鉤子分為銅,銀,金三種。

銅為1,銀為2,金為3;

一開始都是銅鉤子,經過q次變化後,問N節鉤子的數目之和。


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include <sstream>
#include
<vector> #include<cmath> #include<stack> #include<time.h> #include<ctime> using namespace std; #define inf 1<<30 #define eps 1e-7 #define LD long double #define LL long long #define maxn 1000005 struct node { int L, R, sum = 0, flag; }tree[maxn]; void up(int step) { tree[step].sum
= tree[step * 2].sum + tree[step * 2 + 1].sum; } void build(int step, int L, int R)//建樹 { tree[step].L = L; tree[step].R = R; tree[step].flag = 1;//標記,因為一開始L-R都是銅鉤子,即1; if (tree[step].L == tree[step].R) { tree[step].sum = 1; return; } int mid = (L + R) >> 1
; build(step << 1, L, mid); build(step << 1 | 1, mid + 1, R); up(step); } void change(int step, int x, int y, int val) { if (tree[step].flag == val)//當前step的L-R範圍都是val金屬 { return; } if (tree[step].L == x && tree[step].R == y)//L-R剛好和x-y完全重合,直接改變標記即可 { tree[step].flag = val; return; } if (tree[step].flag)//當前存在標記,但又不和val相同,L-R也不與x-y完全重合 { tree[step * 2].flag = tree[step].flag; tree[step * 2 + 1].flag = tree[step].flag; tree[step].flag = 0;//把當前標記為0,因為已經把標記傳遞到左右子樹了 } int mid = (tree[step].L + tree[step].R) >> 1; if (y <= mid)//在左邊 change(step * 2, x, y, val); else if (x > mid)//右邊 change(step * 2 + 1, x, y, val); else//兩邊都有 { change(step * 2, x, mid, val); change(step * 2 + 1, mid + 1, y, val); } tree[step].sum = tree[step * 2].sum + tree[step * 2 + 1].sum; } int query(int step)//計算數目之和 { if (tree[step].flag)//標記不為0,說明step的L-R都是flag金屬 return (tree[step].R - tree[step].L + 1) * tree[step].flag; else return query(step * 2) + query(step * 2 + 1); } int main() { int T, Case = 1; scanf("%d", &T); while (T--) { int N; scanf("%d", &N); build(1, 1, N); int q, sum = 0; scanf("%d", &q); while (q--) { int x, y, val; scanf("%d%d%d", &x, &y, &val); change(1,x, y, val); } sum = query(1); printf("Case %d: The total value of the hook is %d.\n", Case++,sum); } }