(POJ1698)Just a Hook(又是线段树)

来源:互联网 发布:贵州广电网络官网 编辑:程序博客网 时间:2024/05/16 05:59

又做了几道线段树题目,挑了一道设计到区间修改和区间读取的题目发了上来。本次写线段树的时候就有参照大神的模版,明显代码的清晰程度高了很多。这道题目并没有什么弯弯绕绕,就是一个明显的线段树裸体,不需要经过什么奇怪的分析。
在本题中,我设定线段存在两个参数cnt和chg。其中cnt代表了当前线段的元素和,而chg是一线段的修改标记,意味着当前线段已经被修改了1、2、3.,本题中,由于参照了大神的模版,代码和大神及其相似,之所以要发出来,是因为我觉得在这道题中,我的build函数写的比大神更好。由于钩子的初始情况下全部节点都是1,因此相当于对线段【1,end】进行了一次更新为1的操作。而大神可能是因为这道题比较见到没有仔细想,思维定势没想到。
这里再谈一谈写码习惯,我个人习惯上一个线段是使用超尾来表示的,也就是说我的写码习惯中,l、r代表了区间[l,r),如果有人看我的题解的话注意区分开来。
还有,本题中,认为接受到了修改标记的线段仍然没有被更新,在pushdown中,需要对节点进行更新。但是在调试程序的过程中,发现这么做会稍微增大一些调试的复杂程度。因此打算在以后的题目中尝试另一种写法,也就是线段在接收到修改标记的同时已经进行了更新了。

/*Just a HookTime Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 33108    Accepted Submission(s): 16195Problem DescriptionIn the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length.Now Pudge wants to do some operations on the hook.Let us number the consecutive metallic sticks of the hook from 1 to N. For each operation, Pudge can change the consecutive metallic sticks, numbered from X to Y, into cupreous sticks, silver sticks or golden sticks.The total value of the hook is calculated as the sum of values of N metallic sticks. More precisely, the value for each kind of stick is calculated as follows:For each cupreous stick, the value is 1.For each silver stick, the value is 2.For each golden stick, the value is 3.Pudge wants to know the total value of the hook after performing the operations.You may consider the original hook is made up of cupreous sticks.InputThe input consists of several test cases. The first line of the input is the number of the cases. There are no more than 10 cases.For each case, the first line contains an integer N, 1<=N<=100,000, which is the number of the sticks of Pudge’s meat hook and the second line contains an integer Q, 0<=Q<=100,000, which is the number of the operations.Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3, which defines an operation: change the sticks numbered from X to Y into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 represents the silver kind and Z=3 represents the golden kind.OutputFor each case, print a number in a line representing the total value of the hook after the operations. Use the format in the example.Sample Input11021 5 25 9 3Sample OutputCase 1: The total value of the hook is 24.*/#include<algorithm>#include<iostream>#include<cstdio>#include<cstring>#include<climits>#define MAXN 100000#define Father int l,int r,int pos#define lson l,m,pos << 1#define rson m,r,pos << 1 | 1using namespace std;int cnt[MAXN * 4];//计数值int chg[MAXN * 4];//修改徽记 changevoid PushDown(Father);void PushDown(Father){    if (chg[pos]){        cnt[pos] = (r - l) * chg[pos];        if (l + 1 != r){            chg[pos << 1] = chg[pos];            chg[pos << 1 | 1] = chg[pos];        }        chg[pos] = 0;    }}void build(Father){    chg[1] = 1;}void update(int L,int R,int A,Father){    int m = (l + r) / 2;    PushDown(l, r, pos);    if (L <= l && r <= R)chg[pos] = A;    else if (R <= l || r <= L)return;    else{        update(L, R, A, lson);        update(L, R, A, rson);        PushDown(lson); PushDown(rson);        cnt[pos] = cnt[pos << 1] + cnt[pos << 1 | 1];    }}int enquiry(int L, int R, Father){    int m = (l + r) / 2;    PushDown(l, r, pos);    if (L <= l && r <= R)return cnt[pos];    else if (R <= l || r <= L)return 0;    else return enquiry(L, R, lson) + enquiry(L, R, rson);}//int AllClear(Father){//  PushDown(l,r,pos);//  int m = (l + r) / 2;//  if (l + 1 != r){//      AllClear(lson);//      AllClear(rson);//      PushUp(l, r, pos);//  }//  return 0;//}int main(){    int t, i, j, l, T,N,M;    int a, b, c;    cin >> T;    for (t = 0; t < T; t++){        cin >> N >> M;        build(1, N + 1, 1);        for (i = 0; i < M; i++){            scanf("%d %d %d", &a, &b, &c);            update(a, b + 1, c, 1, N + 1, 1);        }        printf("Case %d: The total value of the hook is %d.\n",t + 1,enquiry(1, N + 1, 1, N + 1, 1));    }    return 0;}