敌兵布阵,线段树入门。

来源:互联网 发布:淘宝网衬衫连衣裙女 编辑:程序博客网 时间:2024/05/19 18:42

题目描述,详见HDU 1166;

线段树的上手题,主要是用来熟悉和理解建树和查询的过程。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<queue>#include<algorithm>using namespace std;const int MAXM=50005;const int MAXN=140001;struct node{    int l,r;    int sum;};int n;int a[MAXM];int sum1;struct node t[MAXN];void build_tree(int l,int r,int num){    if (l==r)    {        t[num].l=l;        t[num].r=r;        t[num].sum=a[l];        return ;    }    int mid=(l+r)/2;    build_tree(l,mid,num*2);    build_tree(mid+1,r,num*2+1);    t[num].l=l;    t[num].r=r;    t[num].sum=t[num*2].sum+t[num*2+1].sum;    return ;}void query(int l,int r,int num){    if (t[num].l>=l&&t[num].r<=r)    {        sum1+=t[num].sum;        return ;    }    int mid=(t[num].l+t[num].r)/2;    if (l>mid) query(l,r,num*2+1);    else if (r<=mid) query(l,r,num*2);    else    {        query(l,r,num*2);        query(l,r,num*2+1);    }}void add(int x,int j,int num){    t[num].sum+=j;    if (t[num].l==x&&t[num].r==x) return ;    int mid=(t[num].l+t[num].r)/2;    if (x>mid) add(x,j,num*2+1);    else if (x<=mid) add(x,j,num*2);}void sub(int x,int j,int num){    t[num].sum-=j;    if (t[num].l==x&&t[num].r==x) return ;    int mid=(t[num].l+t[num].r)/2;    if (x>mid) sub(x,j,num*2+1);    else if (x<=mid) sub(x,j,num*2);}int main(){    int T;    scanf("%d",&T);    int p=1;    while(p)    {        scanf("%d",&n);        for (int i=1;i<=n;i++)            scanf("%d",&a[i]);        memset(t,0,sizeof(t));        build_tree(1,n,1);        string s;        int i,j;        printf("Case %d:\n",p);        while(cin>>s)        {            if (s=="End") break;            cin>>i>>j;            if (s=="Query") {sum1=0; query(i,j,1);printf("%d\n",sum1); }            if (s=="Add") {add(i,j,1); }            if (s=="Sub") {sub(i,j,1); }        }        if (p==T) break;        p++;    }    return 0;}


原创粉丝点击