线段树(lazy)-hdu1689

题目描述:

现在Pudge想做一些操作。让我们将钩子的连续金属棒从1编号到N。对于每个操作,Pudge可以将连续金属棒(编号为X到Y)更改为铜棒、银棒或金棒。钩的总值是N根金属棒的总和。更确切地说,每种棍棒的价值计算如下:对于每个铜棒,其值为1。对于每个银棒,其值为2。对于每个金棒,其值为3。Pudge希望知道在执行操作后钩子的总值。你可以认为原来的钩子是用铜棒做的。

输入:

输入由几个测试用例组成。输入的第一行是实例的数目。不超过10例。对于每种情况,第一行包含一个整数N,1<=N<=100000,它是Pudge的钩子的棒的数量,而第二行包含一个整数Q,0<=Q<=100000,它是操作的数量。接下来的Q行,每行包含三个整数X,Y,1<=X<=Y<=N,Z,1<=Z<=3,它定义了一个操作:将编号从X到Y的棒变为金属类Z,其中Z=1表示铜类,Z=2表示银类,Z=3表示金类。

输出:

对于每种情况,在操作之后用表示钩子总值的行中打印出钩子的总价值。使用示例中的格式。

代码实现:

 1 #include <cstdio>
 2
 3 using namespace std;
 4 const int MAXN = 1e6;
 5 int N;
 6 typedef long long ll;
 7 /*
 8 LL其实代表long long, * 1LL是为了在计算时,把int类型的变量转化为long long,
 9 然后再赋值给long long类型的变量
10 */
11 struct node{
12     int l,r;
13     ll sum,lazy;
14     void update(ll x){
15         sum=1ll*(r-l+1)*x;///1LL是为了在计算时,把int类型的变量转化为long long,然后再赋值给long long类型的变量。
16         lazy=x;
17     }
18 }tree[MAXN<<2];
19
20 void push_up(int x){
21     tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
22 }
23
24 void push_down(int x){
25     ll lazyval=tree[x].lazy;
26     if(lazyval>0){
27         tree[x<<1].update(lazyval);
28         tree[x<<1|1].update(lazyval);
29         tree[x].lazy=0;
30     }
31 }
32
33 void build(int x,int l,int r){
34     tree[x].lazy=tree[x].sum=0;
35     tree[x].l=l;tree[x].r=r;
36     if(l==r){
37         tree[x].sum=1;
38         return;
39     }
40     int mid=(l+r)/2;
41     build(x<<1,l,mid);
42     build(x<<1|1,mid+1,r);
43     push_up(x);
44 }
45
46 void update(int x,int l,int r,ll val){
47     int L=tree[x].l,R=tree[x].r;
48     //printf("?úμ?%d ×ó£o%d óò£o%d\n",x,L,R);
49     if(l<=L && R<=r){
50     //    printf("lazy\n");
51         tree[x].update(val);
52         return ;
53     }
54     push_down(x);
55     int mid=(L+R)/2;
56     if(mid>=l)
57         update(x<<1,l,r,val);
58     if(mid<r)
59         update(x<<1|1,l,r,val);
60     push_up(x);
61 }
62
63 ll query(int x,int l,int r){
64     int L=tree[x].l,R=tree[x].r;
65     if(l<=L && R<=r)
66         return tree[x].sum;
67     push_down(x);
68     int mid=(L+R)/2;
69     ll ans=0;
70     if(mid>=l)
71         ans+=query(x<<1,l,r);
72     if(mid<r)
73         ans+=query(x<<1|1,l,r);
74     return ans;
75 }
76
77 int main(){
78     int T;scanf("%d",&T);
79     int cae=0;
80     while(T--){
81         scanf("%d",&N);
82         build(1,1,N);
83         int M;scanf("%d",&M);
84         while(M--){
85             int l,r;
86             ll val;
87     //        printf("N=%d,M=%d,T=%d\n",N,M,T);
88             scanf("%d%d%lld",&l,&r,&val);
89             update(1,l,r,val);
90         }
91         printf("Case %d: The total value of the hook is %lld.\n",++cae,query(1,1,N));
92     }
93     return 0;
94 }

原文地址:https://www.cnblogs.com/LJHAHA/p/10025462.html

时间: 2024-08-02 14:26:18

线段树(lazy)-hdu1689的相关文章

线段树lazy标记??Hdu4902

Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 335    Accepted Submission(s): 159 Problem Description There is an old country and the king fell in love with a devil. The devil al

fzu 2171 线段树 lazy标记

http://acm.fzu.edu.cn/problem.php?pid=2171      Problem 2171 防守阵地 II Accept: 73    Submit: 256Time Limit: 3000 mSec    Memory Limit : 32768 KB Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵

HDU4902:Nice boat(线段树lazy)

Problem Description There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can't refus

FZU1608 Huge Mission 线段树lazy区间更新+求和

就这破题目坑了我一个大晚上,直到今天一觉醒过来才搞定,原因之一:这题目的题意真的是太狗了,还不如直接看着案例猜来的快啊, 题意:给了你一些区间,x,y,第三个参数w是效率,代表这段时间他的单位时间效率,效率总和就是 (y-x)*w,然后有的时间段会被重复啊,比如前面给了1,4,1,后面又给了2,4,3他们为了是的时间段1,4的效率总和最大肯定是选择  2,4区间的效率值选择3,意思就是后面出现更好的情况就覆盖前面的,问你总得最大效率和 当然这题目坑的原因还有一个就是以前学习线段树 做的时候都是看

POJ 3468 线段树+lazy标记

lazy标记 Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status 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

HDU4893:Wow! Such Sequence!(线段树lazy)

Problem Description Recently, Doge got a funny birthday present from his new friend, Protein Tiger from St. Beeze College. No, not cactuses. It's a mysterious blackbox. After some research, Doge found that the box is maintaining a sequence an of n nu

[hiho 22]线段树-lazy标记的下放

题目描述 之前提到过,线段树之所以更新查询快,是因为区间更新有lazy标记使得不需要每次都操作到叶子节点. 但是如果要操作一个节点时,其父节点上的lazy标记应当被释放,否则该节点无法得到最新的正确结果. 因而lazy标记下放的策略是在需要操作某个节点的子节点时,将该节点的lazy标记全部下放.见第69行. 同时应当注意,给某个节点增加lazy标记时,不要忘了修改该节点的相关统计值.因为更新完该节点后还要马上修改其父节点的统计值.见第80行. 代码如下: #include <stdio.h>

线段树lazy模板 luogu3372

线段树写得很少,这么基本的算法还是要会的-- #include<bits/stdc++.h> using namespace std; inline long long read() { long long x = 0, f = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-') f = -1;ch = getchar(); } while (ch >= '0'&&ch <=

Codeforces 242E. XOR on Segment (二维线段树 lazy操作 xor)

题目链接: http://codeforces.com/problemset/problem/242/E 题意: 给出一个序列,有两种操作,一种是计算l到r的和,另一种是让l到r的数全部和x做异或运算. 思路: from: http://blog.csdn.net/u013912596/article/details/39006317 很显然直接暴力是不可能的,又是两种操作,又想到了线段树..但是这并不简单,异或操作该怎么处理? 异或是一种位运算,如果x的第j位是1,那么说明l到r的每个数的第j

poj 4047 Garden 线段树lazy标记与成段更新

题意: 给长度为n的序列及k(0<k<=n<=200000),m个操作p,x,y.其中(1)p==0:将x位置处的数变为y;(2)p==1:将x,y位置处的数互换.(3)p==2查询x-y位置之间连续k个数的和的最大值. 分析: 求连续区间的和最大,可以把区间看成一个点,这样这n-k+1个区间的最大和可以看做n-k+1个点的最大值,当更新原序列中位置x的值就相当于更新区间中x-k+1到x区间的值,然后用线段树做成段更新.成段更新要用到lazy标记,我的理解是:当更新或query的时候如果