士兵杀敌(四)

题目

解决方案一:线段树   1916ms   47100B   C/C++

可以看到用线段树解决非常的浪费空间

#include <iostream>
#include <cstdio>
using namespace std;
#define L(x) (x<<1)
#define R(x) ((x<<1)+1)
#define M(x,y) ((x+y)>>1)
const int N=1000005;
struct node
{
    int l,r,score;
};
node tree[4*N];
/*
此处建立的线段树为[a,b][b+1,c]类型,由于询问的是点的大小 
*/
void build(int t,int l,int r)
{
    tree[t].l=l;
    tree[t].r=r;
    tree[t].score=0;
    if(l==r)return;
    int mid=M(l,r);
    build(L(t),l,mid);
    build(R(t),mid+1,r);
}
void updata(int t,int l,int r,int inc)
{
    if(tree[t].l>=l && tree[t].r<=r)
    {
        tree[t].score+=inc;
        return;
    }
    int mid=M(tree[t].l,tree[t].r);
    if(r<=mid)updata(L(t),l,r,inc);
    else if(l>mid)updata(R(t),l,r,inc);
    else 
    {
        updata(L(t),l,mid,inc);
        updata(R(t),mid+1,r,inc);
    }
}
void query(int t,int n)
{
    if(tree[t].l==tree[t].r )
    {
        printf("%d\n",tree[t].score);
        return ;
    }
    if(tree[t].score) 
    {
        /*
        这个地方由于写成了tree[L(t)].score=tree[R(t)].score=tree[t].score;而导致错误
        因为当儿子节点修改时,也可能本身就存在着值,所以应该在原有的基础上加上当前的
        score而不是简单复制过去 
        */ 
        tree[L(t)].score+=tree[t].score;
        tree[R(t)].score+=tree[t].score;
        tree[t].score=0;        
    }
    //此处本来不应该有问题,但是由于求mid时少写了M(tree[t].l,tree[t].r) 中的M函数名,让我找bug找了
    //半个小时 
    int mid=M(tree[t].l,tree[t].r);
    if(n<=mid)query(L(t),n);
    else query(R(t),n);
}

int main()
{
    int t,m;
    scanf("%d%d",&t,&m);
    build(1,1,m);
    char cmd[10];
    int a,b,inc;
    while(t--)
    {
        getchar();
        scanf("%s",cmd);
        if(cmd[0]=='A')
        {
            scanf("%d%d%d",&a,&b,&inc);
            updata(1,a,b,inc);
        }
        else 
        {
            scanf("%d",&a);
            query(1,a);
        }
    }
//    system("pause");
    return 0;
}

  

解决方案二:树状数组,由于树状数组就是解决插入一个点查询区间和或者插入一个区间查询一个点的问题的,所以相比线段树更简洁,更高效

 
#include <iostream>
#include <cstdio>
using namespace std;
const int N=1000005;
int c[N];
int m;
int lowbit(int n)
{
    return n&(-n);
}
int get(int n)
{
    int sum=0;
    while(n<m)
    {
        sum+=c[n];
        n+=lowbit(n);
    }
    return sum;
}
void add(int n,int inc)
{
    while(n>0)
    {
        c[n]+=inc;
        n-=lowbit(n);
    }
}
int main()
{
    int t;
    scanf("%d%d",&t,&m);
    char cmd[10];
    int a,b,inc;
    while(t--)
    {
        getchar();
        scanf("%s",cmd);
        if(cmd[0]=='A')
        {
            scanf("%d%d%d",&a,&b,&inc);
            add(a-1,-inc);
            add(b,inc);
        }
        else 
        {
            scanf("%d",&a);
            printf("%d\n",get(a));
        }
    }
 //   system("pause");
    return 0;
}
        

  

原文地址:https://www.cnblogs.com/hpustudent/p/2129638.html