线段树 区间更新 HDU1698

Just a Hook

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9758    Accepted Submission(s): 4776

Problem Description

In 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.

Input

The 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.

Output

For 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 Input

1 10 2 1 5 2 5 9 3

Sample Output

Case 1: The total value of the hook is 24.

****************************************/\*\/*/\*\/*************************************************************

时间总是不够,并且时间还趋于零散化,以至于我都不得不思考我是不是该晚些睡了,这样就可以有一大段完整的时间,(至少近期来说只是说一说,如果事情越来越多再晚睡吧)有时候也很无语,上篇博客写到一半机房要关门,只好强行发上去当保存了,这里对看过我那篇博客的人说抱歉,等我有时间在补上去。

这道题的代码风格不是模仿学校课件里的,因为我觉得刘汝佳的更好一些。(以上全是废话)注释都写在代码里了。

 1 #include<stdio.h>
 2 const int maxn=100050;
 3 int sumv[maxn<<2];
 4 int setv[maxn<<2];
 5 void pushup(int rt){///更新当前值
 6     sumv[rt]=sumv[rt<<1]+sumv[rt<<1|1];
 7 }
 8 void pushdown(int rt,int x){///当此节点改变时,更新此节点,并且传递至下一节点
 9     int lc=rt<<1,rc=rt<<1|1,mid=x>>1;
10     if(setv[rt]>=0){
11         setv[rt<<1]=setv[rt<<1|1]=setv[rt];
12         sumv[lc]=(x-mid)*setv[rt];
13         sumv[rc]=mid*setv[rt];
14         setv[rt]=-1;
15     }
16 }
17 void creat(int l,int r,int rt){///特有的建树,因为已经题中总要初始化
18     setv[rt]=-1;
19     sumv[rt]=1;
20     if(l == r) return ;
21     int mid=(l+r)>>1;
22     creat(l,mid,rt<<1);
23     creat(mid+1,r,rt<<1|1);
24     pushup(rt);///每一个节点在子节点建立完成更新
25 }
26 void update(int l,int r,int x,int L,int R,int rt){///数据更新
27     if(l<=L&&r>=R){///当次节点完全覆盖了要更新区间一部分时在次子树的更新结束
28         setv[rt]=x;///更新进程结束
29         sumv[rt]=x*(R-L+1);
30         return ;
31     }
32     pushdown(rt,R-L+1);///更新数据下移并消除此节点的
33     int mid=(L+R)>>1;
34     if(l<=mid) update(l,r,x,L,mid,rt<<1);///如左边有更新,则更新左边
35     if(r>mid) update(l,r,x,mid+1,R,rt<<1|1);///右边有更新则更新右边
36
37     pushup(rt);///更新此节点
38 }
39 int main()
40 {
41     int t, n,q;
42     int k=1;
43     int a,b,c;
44     scanf("%d",&t);
45     while(t--){
46         scanf("%d%d",&n,&q);
47         creat(1,n,1);
48
49         for(int i=0;i<q;i++){
50            scanf("%d%d%d",&a,&b,&c);
51            update(a,b,c,1,n,1);
52           /* for(int j=1;j<20;j++){
53             printf("a%d = %d\n",j,sumv[j]);}*/
54         }
55        printf("Case %d: The total value of the hook is %d.\n",k++,sumv[1]);
56
57     }
58 }

时间: 2024-10-19 19:32:33

线段树 区间更新 HDU1698的相关文章

线段树区间更新hdu1698

第一种是sum存放每个点的值,然后区间更新,把需要更新的父亲的sum设为-1,代表此区间有被更新过,就不由挪动子节点了. vj上跑的时间这个快一点. 另一种lazy标志位,区间更新时,把lazy标志位设为1,当查找的区间含lazy过的,就变更子节点位原来的值,所以需要一个tag记录原来的值. </pre><pre name="code" class="cpp">#include<bits/stdc++.h> using names

HDU1698线段树区间更新

原题http://acm.hdu.edu.cn/showproblem.php?pid=1698 Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16935    Accepted Submission(s): 8427 Problem Description In the game of DotA, Pudge

HDU 1689 Just a Hook 线段树区间更新求和

点击打开链接 Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18894    Accepted Submission(s): 9483 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

Hdu 3966 Aragorn&#39;s Story (树链剖分 + 线段树区间更新)

题目链接: Hdu 3966 Aragorn's Story 题目描述: 给出一个树,每个节点都有一个权值,有三种操作: 1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x: 2:( D, i, j, x ) 从i到j的路径上经过的节点全部都减去x: 3:(Q, x) 查询节点x的权值为多少? 解题思路: 可以用树链剖分对节点进行hash,然后用线段树维护(修改,查询),数据范围比较大,要对线段树进行区间更新 1 #include <cstdio> 2 #include

HDU 5023 A Corrupt Mayor&#39;s Performance Art 线段树区间更新+状态压缩

Link:  http://acm.hdu.edu.cn/showproblem.php?pid=5023 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <cmath> 8 using namesp

hihocoder 1080 线段树(区间更新)

题目链接:http://hihocoder.com/problemset/problem/1080 , 两种操作的线段树(区间更新). 这道题前一段时间一直卡着我,当时也是基础不扎实做不出来,今天又想了想其实还是比较简单的,也只能怪自己太弱了. 这道题坑就坑在是有两个操作:set和add,所以lazy标记数组就需要两个,但是有一点要考虑的是一个区间上set与add的先后关系——如果对于一个区间set和add标记同时存在,那么应该如果处理:一种情况set在add之前,那么就按照正常顺序来就可以了:

(简单) POJ 3468 A Simple Problem with Integers , 线段树+区间更新。

Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval. 题意

HDU 5023 A Corrupt Mayor&#39;s Performance Art(线段树区间更新)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色,有两种操作: P a b c  把区间a到b涂成c颜色 Q a b 查询区间a到b的颜色 线段树区间更新,每个节点保存的信息有,存储颜色的c,30种颜色可以压缩到一个int型里面存储,然后还有一个tot,表示这个区间一共有多少种颜色. 对于P操作,依次往下寻找,找要更新的区间,找到要更新的区间之前