您的位置:首页 > 其它

hdu -1698 很水的线段树 lazy

2016-03-04 14:30 288 查看
题意: 屠夫有一个钩子,由n节棍子组成(编号:1-n),每节棍子可以是金-3,银-2,铜-1的材质。原本是铜组成的,会有几个操作,每一个操作是:输入l,r,num,然后把编号为[l,r]的棍子材质替换为num。求最后的所有棍子材质和。

只有一个知识点 那就是lazy,懒惰标记。

下面贴一下我我自己的代码,注解 都写在下面。

题目比较水,我也写得比较水,最后那个查询求和可以优化。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const int MAXN = 100005;
struct node{
int l,r;
int lazy;      //懒惰标记
int val;      //表示材质

}segTree[MAXN*4];
void build(int L,int R,int n){ //建树
segTree
.l=L;
segTree
.r=R;
segTree
.lazy=0;
segTree
.val=1;
if(L==R)
return;
int mid=(L+R)/2;
build(L,mid,2*n);
build(mid+1,R,2*n+1);
}
void push_down(int n){  //更新懒惰标记的左右子树
if(segTree
.lazy){
segTree
.lazy=0;  //一定不要忘记这一步取消懒惰标记,很容易忘记这一步导致程序崩溃。
segTree[n<<1].val=segTree
.val;
segTree[(n<<1)|1].val=segTree
.val;
segTree[n<<1].lazy=1;
segTree[(n<<1)|1].lazy=1;
}
}
void update(int l,int r,int n,int ll){    //更新区间
if(segTree
.l==l && segTree
.r==r){
segTree
.lazy=1;
segTree
.val=ll;
return;
}
push_down(n);
int mid=(segTree
.l + segTree
.r)/2;
if(r<=mid) update(l,r,n<<1,ll);
else if(l>mid) update(l,r,(n<<1)|1,ll);
else{
update(l,mid,n<<1,ll);
update(mid+1,r,(n<<1)|1,ll);
}
}
int query(int i,int u){        //查询
if(segTree[i].l == u && segTree[i].r == u)
return segTree[i].val;
push_down(i);
int mid=(segTree[i].l + segTree[i].r)/2;
if(u<=mid) return query(i<<1,u);
else return query((i<<1)|1,u);
}
int main()
{
int t;
freopen("1.txt","r",stdin);
scanf("%d",&t);
for(int num=1;num<=t;num++){
printf("Case %d: ",num);
int n,q;
scanf("%d %d",&n,&q);
build(1,n,1);
while(q--){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
update(x,y,1,z);
}
int ans=0;
for(int i=1;i<=n;i++){
ans+=query(1,i);
}
printf("The total value of the hook is %d.\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: