其他分享
首页 > 其他分享> > C - 敌兵布阵

C - 敌兵布阵

作者:互联网

   题目:

题目网址:Problem - 1166 (hdu.edu.cn)

  思路:

对N个数据进行单个的增加或者减少,并随时获取一段数据的和;

普通的方法只能让增减和查询其中一个的复杂度为O(n);

这里我就需要用的线段树进行存储让两个步骤的复杂度都为O(log n);

线段树就是用空间来代替时间;

首先要对数据进行初始化构建线段树,在这里我们用数组来存储;

首先从总和为tree数组的开头在以下标node,node*2+1为左孩子,node*2+2为右孩子

以完全二叉树的形式存储数据的和;

构建tree数组的时候利用递归去操作;

  代码实现:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct
{
    int a,b,sum;
}t[140000];//在这里我们用结构体数组,顺便存储左右端点值
int r[50010],summ,k;
void buildd(int x,int y,int num)//构造线段树
{

    t[num].a=x;//存储左右端点值
    t[num].b=y;
    if(x==y)
        t[num].sum=r[y];//递归出口,当左右相等时就等于只剩下一个点就等于数据本身
    else
    {
        buildd(x,(x+y)/2,num*2);//取中间值分开成两个区间都进行递归
        buildd((x+y)/2+1,y,num*2+1);
        t[num].sum=t[num*2].sum+t[num*2+1].sum;//递归上到最后就会慢慢向上进行数据相加
    }
}
void query(int x, int y, int num)//查找
{
    if(x<=t[num].a&&y>=t[num].b)//递归出口递归区间在所给范围内
        summ+=t[num].sum;
    else{
        int minn=(t[num].a+t[num].b)/2;//区间中间值
        if(x>minn) query(x,y,num*2+1);//如果大于中间值只递归右孩子
        else if(y<=minn)//如果小于只递归左孩子
            query(x,y,num*2);
        else  //如果没有就都递归
        {  
            query(x,y,num*2);
            query(x,y,num*2+1);
        }
    }
}
void update(int x, int y, int num)//数据的更新
{
    t[num].sum+=y;//对总和先进行更新
    if(t[num].a==x&&t[num].b==x) return ;//递归出口当左右端点相等时
    if (x>(t[num].a+t[num].b)/2) update(x,y,num*2+1);//如果区间包括x就进行递归
    else update(x,y,num*2);
}
int main()
{
    int t;
    int cnt=0;
    cin>>t;
    while(t--)
    {
        int n,m;
        char ch[10];
        cin>>k;
        r[0]=0;
        for(int i=1;i<=k;i++)
            cin>>r[i];//输入数据先存储在一个数组里
        buildd(1,k,1);//在进行线段树构建
        printf("Case %d:\n",++cnt);
        while(cin>>ch)
        {//对输入操作进行判断,并作出对应操作
            if(strcmp(ch,"End")==0)
                break;
            else if(strcmp(ch,"Query")==0)
            {
                cin>>n>>m;
                summ=0;
                query(n,m,1);
                printf("%d\n",summ);
            }
            else if(strcmp(ch,"Add")==0)
            {
                cin>>n>>m;
                update(n,m,1);
            }
            else if(strcmp(ch,"Sub")==0)
            {
                cin>>n>>m;
                update(n,-1*m,1);
            }
        }
    }
    return 0;
}

 

标签:ch,num,递归,int,sum,else,敌兵,布阵
来源: https://www.cnblogs.com/wangdy/p/15098936.html