题目链接 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;
}