现在的位置: 首页 > 综合 > 正文

NYOJ 116:士兵杀敌 第一次用树状数组AC题目

2018年05月25日 ⁄ 综合 ⁄ 共 939字 ⁄ 字号 评论关闭

        两个月前用暴力穷举做这道题目,超时!一直不得其解,今天学了一下树状数组,刚刚用这个在线数据结构AC了这道题目。

       这道题目的URL:http://acm.nyist.net/JudgeOnline/problem.php?pid=116

  树状数组的功能:查询一段区间的值的和。并且修改和查询的复杂度都是log(N)的。比起简单的暴力求和要快的多。

        我这里给出自己的代码给大家参考

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

const int Max = 1000000 + 10;

int c[Max]; //树状数组
int num; //数组大小 

//求value变量的二进制表示的最后一个1所在位的权值
int lowbit(int value)
{
	return (value & (value ^ (value - 1)));
}

//修改pos位及其所有祖先的值
void modify(int pos, int value)
{
	while(pos <= num)
	{
		c[pos] += value;
		pos += lowbit(pos);
	}
}

//求1到pos的和
int sum(int pos)
{
	int total = 0;
	while(pos > 0)
	{
		total += c[pos];
		pos -= lowbit(pos);
	}
	return total;
}

int main()
{
	int m, value; //
	char ins[10];
	int a, b;
	scanf("%d%d", &num, &m);
	
	memset(c, 0, sizeof(c)); //初始化
	for(int i=1; i<=num; i++)
	{
		scanf("%d", &value);
		modify(i, value);
	}
	
	for(int i=0; i<m; i++)
	{
		scanf("%s%d%d", ins, &a, &b);
		switch(ins[0])
		{
		case 'A':
			modify(a, b);
			break;
		case 'Q':
			int cnt = sum(b) - sum(a-1);
			printf("%d\n", cnt);
			break;
		}
	}
	system("pause");
	return 0;
}

,关于树状数组的知识大家可以百度百科一下。

抱歉!评论已关闭.