线段树模板

单点更新(HDU1166)

#include <cstdio>
#include <iostream>
using namespace std;
const int MAXN=2e5+10;
const int MAXNODE=MAXN<<2;//一般开到4倍
int sum;
struct node
{
  int l;
  int r;
  int value;
}tree[MAXNODE];
int father[MAXN];//用来储存第x个元素在线段数的结点位置
void BuildTree(int i,int l,int r)
{
    tree[i].l=l;
    tree[i].r=r;
    tree[i].value=0;
    if(l==r)
    {
      father[l]=i;
      return;
    }
    BuildTree(i<<1,l,(l+r)/2);
    BuildTree((i<<1)+1,(l+r)/2+1,r);
}
void UpTree(int ri)
{
    if(ri==1)
        return;
   int fi=ri/2;
   int a=tree[fi<<1].value;
   int b=tree[(fi<<1)+1].value;
   tree[fi].value=a+b;
   UpTree(fi);
}
int MAX;
void Query(int i,int l,int r)
{
  if(tree[i].l==l&&tree[i].r==r)
  {
     sum+=tree[i].value;
      return;
  }
  i=i<<1;
  if(l<=tree[i].r)
  {
      if(r<=tree[i].r) Query(i,l,r);
      else Query(i,l,tree[i].r);
  }
  i++;
  if(r>=tree[i].l)
  {
      if(l>=tree[i].l)Query(i,l,r);
      else Query(i,tree[i].l,r);
  }
}
int main()
{
    int n,m,g,a,b,t;
    char ch[100];
       scanf("%d",&t);
    for(int k=1;k<=t;k++)
    {
       scanf("%d",&n);

        BuildTree(1,1,n);
      for(int i=1;i<=n;i++)
      {
          scanf("%d",&g);
          tree[father[i]].value=g;
          UpTree(father[i]);
      }
      printf("Case %d:\n",k);
          while(scanf(" %s",ch)!=EOF)
          {
              sum=0;
           if(ch[0]=='E')
            break;
           scanf("%d%d",&a,&b);
           if(ch[0]=='Q')
           {
            Query(1,a,b);
            printf("%d\n",sum);
           }
           else if(ch[0]=='A')
           {
             tree[father[a]].value+=b;
             UpTree(father[a]);
           }
           else if(ch[0]=='S')
           {

             tree[father[a]].value-=b;
             UpTree(father[a]);
           }
           }
    }

  return 0;
}

 区间更新(HDU1698)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN=1e5+100;
typedef long long ll;
int sum[MAXN<<2];
int add[MAXN<<2];
int res;
struct node
{
    int l;
    int r;
}tree[MAXN<<2];
void PushUp(int rt)
{
  sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
    if(add[rt])
    {
      add[rt<<1]=add[rt];
      add[rt<<1|1]=add[rt];
      sum[rt<<1]=add[rt]*(m-m/2);
      sum[rt<<1|1]=add[rt]*(m/2);
      add[rt]=0;
    }
}
void BuildTree(int l,int r,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    add[rt]=0;
    if(l==r)
    {
      sum[rt]=1;
      return;
    }
    int mid=(tree[rt].l+tree[rt].r)/2;
    BuildTree(l,mid,rt<<1);
    BuildTree(mid+1,r,rt<<1|1);
    PushUp(rt);
}
void Update(int c,int l,int r,int rt)
{
    if(tree[rt].l==l&&tree[rt].r==r)
    {
        sum[rt]=c*(r-l+1);
        add[rt]=c;
        return;
    }
    int mid=(tree[rt].l+tree[rt].r)/2;
    PushDown(rt,tree[rt].r-tree[rt].l+1);
    if(r<=mid) Update(c,l,r,rt<<1);
    else if(l>mid)Update(c,l,r,rt<<1|1);
    else
    {
        Update(c,l,mid,rt<<1);
        Update(c,mid+1,r,rt<<1|1);
    }
    PushUp(rt);
}
void Query(int l,int r,int rt)
{
    if(tree[rt].l==l&&tree[rt].r==r)
    {
      res+=sum[rt];
      return;
    }
    int mid=(tree[rt].l+tree[rt].r)/2;
    PushDown(rt,tree[rt].r-tree[rt].l+1);
    if(r<=mid)Query(l,r,rt<<1);
    else if(l>mid)Query(l,r,rt<<1|1);
    else
    {
        Query(l,mid,rt<<1);
        Query(mid+1,r,rt<<1|1);
    }
    PushUp(rt);
}
int main()
{
    int t,n,q,a,b,c,Case;
    scanf("%d",&t);
    Case=0;
    while(t--)
    {
         Case++;
         scanf("%d",&n);
         BuildTree(1,n,1);
         scanf("%d",&q);

         while(q--)
         {
            scanf("%d%d%d",&a,&b,&c);
            Update(c,a,b,1);

         }
         res=0;
         Query(1,n,1);

         printf("Case %d: The total value of the hook is %d.\n",Case,res);
    }
    return 0;
}

 

posted @ 2017-08-13 13:59  hinata_hajime  阅读(204)  评论(0编辑  收藏  举报