您的位置:首页 > 其它

hdu 1698Just a Hook(线段树区间修改)

2016-07-24 16:33 323 查看
题目链接

题意:

题目意思是说讲整个区间的每个元素值提前全部置为1 然后给出三个数a b c 表示将区间a到b的值都置为c,然后求经过几次操作后整个区间总和。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int MAXN=100010;
struct Node
{
int l,r;
int lazy,tag;
int sum;
}segTree[MAXN*4];
void Build(int i,int l,int r)    //建树
{
segTree[i].l=l;
segTree[i].r=r;
segTree[i].lazy=0;
segTree[i].tag=0;
if(l==r)
{
segTree[i].sum=1;          //普通线段树改成元素值即可
return;
}
int mid=(l+r)>>1;
Build(i<<1,l,mid);
Build((i<<1)|1,mid+1,r);
segTree[i].sum=segTree[i<<1].sum+segTree[(i<<1)|1].sum;
}
void update(int i,int l,int r,int v)
{
if(segTree[i].l==l&&segTree[i].r==r)    //成段更新
{
segTree[i].lazy=1;
segTree[i].tag=v;
segTree[i].sum=(r-l+1)*v;
return;
}
int mid=(segTree[i].l+segTree[i].r)>>1;
if(segTree[i].lazy==1)
{
segTree[i].lazy=0;
update(i<<1,segTree[i].l,mid,segTree[i].tag);
update((i<<1)|1,mid+1,segTree[i].r,segTree[i].tag);
segTree[i].tag=0;
}
if(r<=mid) update(i<<1,l,r,v);
else if(l>mid)update((i<<1)|1,l,r,v);
else
{
update(i<<1,l,mid,v);
update((i<<1)|1,mid+1,r,v);
}
segTree[i].sum=segTree[i<<1].sum+segTree[(i<<1)|1].sum;
}

int query(int i,int l,int r)      //查询过程
{
if(segTree[i].lazy)
return segTree[i].tag*(r-l+1);
if(segTree[i].l==l&&segTree[i].r==r)
return segTree[i].sum;
int m=(segTree[i].l+segTree[i].r)/2;
if(r<=m) return query(i*2,l,r);
else if(l>m) return query(i*2+1,l,r);
else return query(i*2,l,m)+query(i*2+1,m+1,r);
}

int main()
{
int x,y,z;
int n;
int m;
int T;
scanf("%d",&T);
int iCase=0;
while(T--)
{
iCase++;
scanf("%d%d",&n,&m);
Build(1,1,n);
while(m--)
{
scanf("%d%d%d",&x,&y,&z);
update(1,x,y,z);
}
printf("Case %d: The total value of the hook is %d.\n",iCase,query(1,1,n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: