hdoj 1166 敌兵布阵

    暴力超时,这道题可以用线段树做,因为更新的是单个节点,我们也可以用数组数组来做,我将两种方法的代码都给出

    数组数组最适宜的用途就是区间求和和点的更新,但树状数组并不适用于区间的更新问题,也不是做不到,比较麻烦且难理解,有兴趣的可以看看这个http://blog.csdn.net/xindoo/article/details/8748410


//树状数组
#include<stdio.h>

int n,ans[50005],f[50005];

int lowbit(int n)
{
    return n&(-n);
}

void add(int i,int v)
{
    while(i <= n)
    {
        ans[i] += v;
        i += lowbit(i);
    }
}

int query(int n)
{
    int s = 0;
    while(n)
    {
        s += ans[n];
        n -= lowbit(n);
    }
    return s;
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int j = 1;j <= t; j++)
    {
        scanf("%d",&n);
        for(int l = 1; l <= n;l++)
        {
            scanf("%d",&f[l]);
            f[l] += f[l-1];
        }
        for(int l = 1; l <= n; l++)
            ans[l] = f[l]-f[l-lowbit(l)];
        printf("Case %d:\n",j);
        while(1)
        {
            char s[20];
            int a,b;
            scanf("%s",s);
            if (s[0] == 'E') break;
            scanf("%d%d",&a,&b);
            if (s[0] == 'A') add(a,b);
            if (s[0] == 'S') add(a,-b);
            if (s[0] == 'Q') printf("%d\n",query(b)-query(a-1));
        }
    }
    return 0;
}

//线段树解法
#include <stdio.h>
#include <string.h>
#define maxn 50005

struct node
{
    int l, r, m;
    int sum;
}tree[maxn<<2];

int a[maxn];

void build(int l, int r, int o)
{
    tree[o].l = l;
    tree[o].r = r;
    int m = (l+r)>>1;
    tree[o].m = m;
    if (l == r)
    {
        tree[o].sum = a[l];
        return;
    }
    build(l, m, o<<1);
    build(m+1, r, (o<<1)+1);
    tree[o].sum = tree[o<<1].sum + tree[(o<<1)+1].sum;
 }

void update(int l, int v, int o)
{
    tree[o].sum += v;
    if (tree[o].l == l && tree[o].r == l)
        return;
    if (l <= tree[o].m)
        update(l, v, o<<1);
    else
        update(l, v, (o<<1)+1);
}

int query(int l, int r, int o)
{
    if (tree[o].l == r && tree[o].r == r)
        return tree[o].sum;
    if (tree[o].m >= r)
        return query(l, r, o<<1);
    else if (tree[o].m <l)
        return query(l, r, (o<<1)+1);
    else
        return query(l, tree[o].m, o<<1) + query(tree[o].m+1, r, (o<<1)+1);
}

int main()
{
    int t, n;
    scanf("%d",&t);
    for (int j = 1; j <= t; j++)
    {
        scanf("%d",&n);
        for (int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        build(1, n, 1);
        printf("Case %d:\n",j);
        while(1)
        {
            char s[20];
            int l, r;
            scanf("%s",s);
            if (s[0] == 'E')
                break;
            scanf("%d%d",&l,&r);
            if (s[0] == 'A')
                update(l, r, 1);
            else if (s[0] == 'S')
                update(l, -r, 1);
            if (s[0] == 'Q')
                printf("%d\n",query(l, r, 1));
        }
    }
    return 0;
}


展开阅读全文

极简JAVA学习营第四期(报名以后加助教微信:eduxy-1)

01-19
想学好JAVA必须要报两万的培训班吗? Java大神勿入 如果你: 零基础想学JAVA却不知道从何入手 看了一堆书和视频却还是连JAVA的环境都搭建不起来 囊中羞涩面对两万起的JAVA培训班不忍直视 在职没有每天大块的时间专门学习JAVA 那么恭喜你找到组织了,在这里有: 1. 一群志同道合立志学好JAVA的同学一起学习讨论JAVA 2. 灵活机动的学习时间完成特定学习任务+每日编程实战练习 3. 热心助人的助教和讲师及时帮你解决问题,不按时完成作业小心助教老师的家访哦 上一张图看看前辈的感悟:     大家一定迫不及待想知道什么是极简JAVA学习营了吧,下面就来给大家说道说道: 什么是极简JAVA学习营? 1. 针对Java小白或者初级Java学习者; 2. 利用9天时间,每天1个小时时间; 3.通过 每日作业 / 组队PK / 助教答疑 / 实战编程 / 项目答辩 / 社群讨论 / 趣味知识抢答等方式让学员爱上学习编程 , 最终实现能独立开发一个基于控制台的‘库存管理系统’ 的学习模式 极简JAVA学习营是怎么学习的?   如何报名? 只要购买了极简JAVA一:JAVA入门就算报名成功!  本期为第四期极简JAVA学习营,我们来看看往期学员的学习状态: 作业看这里~   助教的作业报告是不是很专业 不交作业打屁屁 助教答疑是不是很用心   有奖抢答大家玩的很嗨啊     项目答辩终于开始啦   优秀者的获奖感言   这是答辩项目的效果     这么细致的服务,这么好的氛围,这样的学习效果,需要多少钱呢? 不要1999,不要199,不要99,只要9.9 是的你没听错,只要9.9以上所有就都属于你了 如果你: 1、 想学JAVA没有基础 2、 想学JAVA没有整块的时间 3、 想学JAVA没有足够的预算 还等什么?赶紧报名吧,抓紧抢位,本期只招300人,错过只有等时间待定的下一期了   报名请加小助手微信:eduxy-1    
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值