线段树(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 - 4578 Transformation(线段树区间修改)
题解报告:hdu 1698 Just a Hook(线段树lazy标记的运用)