【线段树区间更新】hdu1698 Just a Hook
题目大意
第一行输入t组数据
对于每组数据
第一行n (数据量)
第二行q (操作数)
接下来q行
x y z (表示把[x,y]的数据都 变成z)
初始条件所有数据都是1;
Sample Input
1
10
2
1 5 2
5 9 3
Sample Output
Case 1: The total value of the hook is 24.
解题思路
线段树区间更新lazy标记
AC代码
///线段树区间求和
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100000+100;
struct p
{
int l,r,sum;
}tree[maxn<<2];
int lazy[maxn<<2];
int cnt;
void build(int i,int l,int r)
{
tree[i].l=l;
tree[i].r=r;
tree[i].sum=0;
if(l==r)
{
tree[i].sum=1;
return;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
void update(int i,int l,int r,int v)
{
if(tree[i].l>=l&&tree[i].r<=r)
{
tree[i].sum=(tree[i].r-tree[i].l+1)*v;
lazy[i]=v;
return;
}
if(lazy[i]>0)
{
lazy[i*2]=lazy[i*2+1]=lazy[i];
tree[i*2].sum=lazy[i]*(tree[i*2].r-tree[i*2].l+1);
tree[i*2+1].sum=lazy[i]*(tree[i*2+1].r-tree[i*2+1].l+1);
lazy[i]=0;
}
int mid=(tree[i].l+tree[i].r)>>1;
if(r<=mid) update(i*2,l,r,v);
else if(l>mid) update(i*2+1,l,r,v);
else
{
update(i*2,l,mid,v);
update(i*2+1,mid+1,r,v);
}
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
int q(int i,int l,int r)
{
if(tree[i].l==l&&tree[i].r==r)
{
return tree[i].sum;
}
int mid=(tree[i].l+tree[i].r)>>1;
if(r<=mid) {return q(i*2,l,r);}
else if(l>mid) { return q(i*2+1,l,r);}
else
{
return q(i*2,l,mid)+q(i*2+1,mid+1,r);
}
}
int main()
{
int t,n,Q,i,j,x,y,z;
scanf("%d",&t);
int k=1;
while(t--)
{
scanf("%d%d",&n,&Q);
cnt=0;
build(1,1,n);
while(Q--)
{
scanf("%d%d%d",&x,&y,&z);
update(1,x,y,z);
}
printf("Case %d: The total value of the hook is %d.\n",k++,q(1,1,n));
for(int i=0;i<n*4+7;i++)
lazy[i]=0;
}
return 0;
}