HDU - 1698 Just a Hook(线段树)

题目链接:戳我戳我

题目大意:

       给出一段序列,一开始每个数字的价值都是1,通过一些操作把某些区间数的价值改为2或者3,最后输出这段序列的总价值。

题目思路:

       算是比较裸的线段树模板题了(毕竟我这种菜鸡都能做出来T_T)显然是求区间和,只不过输入数字是多少(2或3),就把该区间的值改为2*区间长度或者3*区间长度,至于子节点的修改,完全参照区间修改的tag操作就行。注意这道题不是累加,因为并不是要把区间的数加上某个值,而是直接改变成某个值。直接拿上篇博客写的线段树区间修改模板改一下就可以了;

题目代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 100005

using namespace std;
struct node
{
     int l,r;
     int sum,tag;
}tree[maxn<<2];

void build(int k,int l,int r)
{
     tree[k].l=l;tree[k].r=r;
     tree[k].tag=0;
     if(l==r)
     {
          tree[k].sum=1;
          return;
     }
     int mid=(l+r)>>1;
     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
     tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}

void change(int k)
{
     if(tree[k].l!=tree[k].r)//把累加都换成赋值,因为是直接“变成”而不是“加上”
     {
          tree[k<<1].sum=(tree[k<<1].r-tree[k<<1].l+1)*tree[k].tag;
          tree[k<<1|1].sum=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].tag;
          tree[k<<1].tag=tree[k].tag;
          tree[k<<1|1].tag=tree[k].tag;
     }
     tree[k].tag=0;
}
void add(int k,int l,int r,int x)
{
      if(tree[k].tag)
          change(k);
      tree[k].sum=(r-l+1)*x;
      if(tree[k].l==l&&tree[k].r==r)
      {
           tree[k].tag=x;//注意这里直接赋值
           return;
      }
      int mid=(tree[k].l+tree[k].r)>>1;
      if(l>=mid+1)
          add(k<<1|1,l,r,x);
      else if(r<=mid)
          add(k<<1,l,r,x);
      else
      {
           add(k<<1,l,mid,x);add(k<<1|1,mid+1,r,x);
      }
      tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
int query(int k,int l,int r)
{
     int res;
     if(tree[k].tag)
          change(k);
     if(tree[k].l==tree[k].r)
          return tree[k].sum;
     int mid=(tree[k].l+tree[k].r)>>1;
     if(l>=mid+1)
          res=query(k<<1|1,l,r);
     else if(r<=mid)
          res=query(k<<1,l,r);
     else
          res=query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
     tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
     return res;
}
int main(void)
{
     int t,n,m;
     int x,y,z;
     int kase=0;
     scanf("%d",&t);
     while(t--)
     {
          scanf("%d%d",&n,&m);
          build(1,1,n);
          for(int i=1;i<=m;++i)
          {
               scanf("%d%d%d",&x,&y,&z);
               add(1,x,y,z);
          }
          printf("Case %d: The total value of the hook is %d.\n",++kase,query(1,1,n));
     }
     return 0;
}

呼呼

猜你喜欢

转载自blog.csdn.net/destiny1507/article/details/81675323