线段树(lazy)-hdu1689

Posted ljhaha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树(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
",x,L,R);
49     if(l<=L && R<=r){
50     //    printf("lazy
");
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,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.
",++cae,query(1,1,N));
92     }
93     return 0;
94 }

 

以上是关于线段树(lazy)-hdu1689的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1556 线段树 lazy

HDU - 4578 Transformation(线段树区间修改)

HDU 1698 Just a Hook 线段树区间更新

题解报告:hdu 1698 Just a Hook(线段树lazy标记的运用)

HDU 3911 Black And White (线段树区间合并 + lazy标记)

HDU1698 Just a Hook 线段树+成段更新+lazy标记