您的位置:首页 > 其它

成段改A为B更新区间求和 hdu 1698 Just a Hook

2015-10-11 15:46 288 查看
  题目链接   hdu 1698 Just a Hook

  题目大意:给你n个数(初始时每个数的值为1),m个操作,每个操作把区间[l,r]里的数更新为c,问最后这n个数的和是多少。

  解题思路:O(-1)

#include <cstdio>
#include <iostream>
using namespace std;

const int maxn=100005;
int tree[4*maxn];
int flag[4*maxn];

void down(int u, int l, int r)
{
if(flag[u])
{
int mid=(l+r)>>1;
tree[2*u]=(mid-l+1)*flag[u];
tree[2*u+1]=(r-mid)*flag[u];
flag[2*u]=flag[u];
flag[2*u+1]=flag[u];
flag[u]=0;
}
}

void build(int u, int l, int r)
{
flag[u]=0;
if(l==r)
{
tree[u]=1;
return ;
}
int mid=(l+r)>>1;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
tree[u]=tree[2*u]+tree[2*u+1];
}

void update(int u, int l, int r, int tl, int tr, int val)
{
if(tl<=l&&r<=tr)
{
tree[u]=(r-l+1)*val;
flag[u]=val;
return ;
}
down(u,l,r);
int mid=(l+r)>>1;
if(tr<=mid)  update(2*u,l,mid,tl,tr,val);
else if(tl>mid) update(2*u+1,mid+1,r,tl,tr,val);
else
{
update(2*u,l,mid,tl,tr,val);
update(2*u+1,mid+1,r,tl,tr,val);
}
tree[u]=tree[2*u]+tree[2*u+1];

}

int getsum(int u, int l, int r, int tl, int tr)
{
if(tl<=l&&r<=tr)
{
return tree[u];
}
down(u,l,r);
int mid=(l+r)>>1;
if(tr<=mid) return getsum(2*u,l,mid,tl,tr);
else if(tl>mid) return getsum(2*u+1,mid+1,r,tl,tr);
else
{
int t1=getsum(2*u,l,mid,tl,tr);
int t2=getsum(2*u+1,mid+1,r,tl,tr);
return t1+t2;
}
}

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