题意:
给你T组数据,N个数(初始时每个数的值为1),M个操作,每个操作把区间[a,b]里的数更新为c,问最后这N个数的和是多少。
分析:
线段树区间修改区间求和。
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1001000;
int n,m,l,r,z,cas;
struct tree{int l,r,sum,lazy;}g[N];
void pushup(int rt){g[rt].sum=g[2*rt].sum+g[2*rt+1].sum;}
void pushdown(int rt)
{
if (g[rt].lazy)
{
g[2*rt].sum=g[rt].lazy*(g[2*rt].r-g[2*rt].l+1);
g[2*rt+1].sum=g[rt].lazy*(g[2*rt+1].r-g[2*rt+1].l+1);
g[2*rt].lazy=g[rt].lazy;
g[2*rt+1].lazy=g[rt].lazy;
g[rt].lazy=0;
}
}
void build(int rt,int l,int r)
{
g[rt].l=l;
g[rt].r=r;
g[rt].sum=r-l+1;
g[rt].lazy=1;
if (l==r) return;
int mid=(l+r)/2;
build(2*rt,l,mid);
build(2*rt+1,mid+1,r);
}
void update(int rt,int ll,int rr,int val)
{
int l=g[rt].l,r=g[rt].r;
if (ll<=l && r<=rr)
{
g[rt].sum=(r-l+1)*val;
g[rt].lazy=val;
} else
{
pushdown(rt);
int mid=(l+r)/2;
if (ll<=mid) update(2*rt,ll,rr,val);
if (rr> mid) update(2*rt+1,ll,rr,val);
pushup(rt);
}
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&z);
update(1,l,r,z);
}
printf("Case %d: The total value of the hook is %d.\n",++cas,g[1].sum);
}
}