HDU 1166 敌兵布阵【简单典型的线段树问题】

来源:互联网 发布:菜鸟网络总部 编辑:程序博客网 时间:2024/05/21 10:25

线段树就是一颗二叉树

不过是区间二叉树。

目前比较板子的就是,建树,区间,查最小值,增添(减少就是负向增添);

所以直接贴代码了:

希望自己可以多理解理解:

#include <bits/stdc++.h>using namespace std ;struct seg//*结构体代替左右区间和当前子节点 {    int l;    int r;    int n;} T[150011];void build(int l,int r,int k) //*建树 {    int mid;    if(l==r)//*如果只有单节点,     {        T[k].l=l;        T[k].r=r;        T[k].n=0;        return ;    }    mid=(l+r)/2;    T[k].l=l;    T[k].r=r;    T[k].n=0;    build(l,mid,2*k);//*左树     build(mid+1,r,2*k+1);//*右树 }void insert(int n,int d,int k) //*单节点更新 。先计算节点位置再更新 {    int mid;    if(T[k].l==T[k].r&&T[k].l==d)    {        T[k].n+=n;        return ;    }    mid=(T[k].l+T[k].r)>>1;    if(d<=mid)insert(n,d,2*k);    elseinsert(n,d,2*k+1);    T[k].n=T[2*k].n+T[2*k+1].n;}int ans;void search(int l,int r,int k)//*从最高节点开始查询 {    int mid;    if(T[k].l==l&&T[k].r==r)    {        ans+=T[k].n;        return ;    }    mid=(T[k].l+T[k].r)>>1;    if(r<=mid)search(l,r,2*k);    else if(l>mid)search(l,r,2*k+1);    else    {        search(l,mid,2*k);        search(mid+1,r,2*k+1);    }}int main(){    int Case,TT;    int n;    int i;    int temp;    char str[11];    int a,b;    scanf("%d",&TT);    for(Case=1; Case<=TT; Case++)    {        scanf("%d",&n);        build(1,n,1);        for(i=1; i<=n; i++)        {            scanf("%d",&temp);            insert(temp,i,1);        }        printf("Case %d:\n",Case);        while(scanf("%s",str),strcmp(str,"End"))        {            scanf("%d%d",&a,&b);            if(strcmp(str,"Add")==0)insert(b,a,1);            else if(strcmp(str,"Sub")==0)insert(-b,a,1);            else            {                ans=0;                search(a,b,1);                printf("%d\n",ans);            }        }    }    return 0;}   

多谢神牛的写法,

神牛博客地址: http://blog.csdn.net/libin56842/article/details/8530086


更新一下自己的写法,没有用结构体;

#include <bits/stdc++.h> using namespace std ;#define N 500005 #define lson l,m,rt<<1  #define rson m+1,r,rt<<1|1  int sum[N<<2];inline void PushPlus(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l, int r, int rt)  {      if(l == r)     {          scanf("%d", &sum[rt]);          return ;     }      int m = ( l + r )>>1;       build(lson);      build(rson);     PushPlus(rt);  }  void updata(int p, int add, int l, int r, int rt)  {      if( l == r )     {         sum[rt] += add;          return ;     }      int m = ( l + r ) >> 1;     if(p <= m)         updata(p, add, lson);      else          updata(p, add, rson);       PushPlus(rt);  }  int search(int L ,int R ,int l , int r , int rt){int ans = 0 ;if(L<=l&&R>=r){return sum[rt];}int m = (l+r)>>1;if(L<=m) ans += search(L,R,lson);if(R>m) ans += search(L,R,rson);return ans ;}int  main(){int t ;cin>>t;char str[5000];for(int i=1;i<=t;i++){int n ;int a , b ;cin>>n;build(1,n,1);printf("Case %d:\n",i);while(scanf("%s",str)&&str[0]!='E'){cin>>a>>b; int m;if(str[0]=='Q'){m=search(a,b,1,n,1);cout<<m<<endl;}else if(str[0]=='A'){updata(a,b,1,n,1);}else {updata(a,-b,1,n,1);}}}return 0 ;}



0 0
原创粉丝点击