hdu1698 Just a Hook(線段樹,區間更新)
阿新 • • 發佈:2019-01-02
題目連結:http://acm.split.hdu.edu.cn/showproblem.php?pid=1698
題意:
某個鉤子由n個小鉤子組成,有q個操作,將某個區間內的小鉤子的材料改變,有金銀銅三中材料,每種材料價錢不同。問最後這個鉤子的價值
注意,題目中預設初始化時,n個小鉤子全為銅
思路:
線段樹,區間更新(不是相加更新),最後輸出根節點的值即可。關鍵在於,如何理出用線段樹來解決這一題,重點是理解更新。
程式碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 100000; int sum[4*maxn+5]; int add[4*maxn+5]; void up(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void down(int rt, int len){ if(add[rt]){ add[rt<<1] = add[rt]; add[rt<<1|1] = add[rt]; sum[rt<<1] = add[rt] * (len-(len>>1)); sum[rt<<1|1] = add[rt] * (len>>1); add[rt] = 0; } } void build(int rt, int l, int r){ if(l==r){ sum[rt] = 1; } else{ int mid = (l+r)>>1; build(rt<<1, l, mid); build(rt<<1|1, mid+1, r); up(rt); } return; } void update(int rt, int val, int x, int y, int l, int r){ if(x<=l && r<=y){ sum[rt] = val*(r-l+1); add[rt] = val; } else{ down(rt, r-l+1); int mid = (l+r)>>1; if(x<=mid) update(rt<<1, val, x, y, l, mid); if(y>mid) update(rt<<1|1, val, x, y, mid+1, r); up(rt); } } int main(){ int t, n, q, x, y, z, cnt=0; scanf("%d", &t); while(t--){ memset(sum, 0, sizeof(sum)); memset(add, 0, sizeof(add)); scanf("%d%d", &n, &q); build(1, 1, n); for(int i=0; i<q; i++){ scanf("%d%d%d", &x, &y, &z); update(1, z, x, y, 1, n); } printf("Case %d: The total value of the hook is %d.\n", ++cnt, sum[1]); } return 0; }