码迷,mamicode.com
首页 > 其他好文 > 详细

nyoj 116 士兵杀敌(四)(线段树区间更新和单点查询)

时间:2016-04-14 14:23:23      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

士兵杀敌(四)

时间限制:2000 ms  |  内存限制:65535 KB
难度:5
描述

南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧。

假设起始时所有人的军功都是0.

输入
只有一组测试数据。
每一行是两个整数T和M表示共有T条指令,M个士兵。(1<=T,M<=1000000)
随后的T行,每行是一个指令。
指令分为两种:
一种形如
ADD 100 500 55 表示,第100个人到第500个人请战,最终每人平均获得了55军功,每次每人获得的军功数不会超过100,不会低于-100。
第二种形如:
QUERY 300 表示南将军在询问第300个人的军功是多少。
输出
对于每次查询输出此人的军功,每个查询的输出占一行。
样例输入
4 10
ADD 1 3 10
QUERY 3
ADD 2 6 50
QUERY 3
样例输出
10
60
来源
[张云聪]原创
上传者
张云聪

当看到是区间更新的时候 就想到再用士兵杀敌(二)区间查询单点更新的方法不行了

肯定会超时  因为以前好像做过一个懒惰标记的线段树 具体也忘记了 

总之算是有了思路 

1.在区间更新数据的时候 只要找到区间即可 无需找到具体的位置

2.查询的时候要一搜到底。

这道题对比着士兵杀敌(二)区间查询单点更新 还是很容易理解的 

代码:

#include <stdio.h>
struct node
{
	int left,right;
	long long num;
}tree[1000000*4];
//初始化线段树 
void build(int left,int right,int root)
{
	tree[root].left=left;
	tree[root].right=right;
	if(left==right)
	{
		tree[root].num=0;
		return ;
	}
	else
	{
		int mid=(left+right)>>1;
		build(left,mid,root*2);
		build(mid+1,right,root*2+1);
		tree[root].num=0;
	}
}
//更新区间值 
void update(int l,int r,int x,int root)
{
	//找到对应区间即可  
	if(tree[root].left==l&&tree[root].right==r)
	{
		tree[root].num+=x;
		return ;
	}
	int mid=(tree[root].left+tree[root].right)>>1;
	if(mid<l)
	update(l,r,x,root*2+1);
	else if(mid>=r)
	update(l,r,x,root*2);
	else
	{
		update(l,mid,x,root*2);
		update(mid+1,r,x,root*2+1);
	}
}
//从根到叶子 一搜到底 
void search(int root,int pos,long long &result)
{
	if(tree[root].left==tree[root].right&&tree[root].left==pos)
	{
		result+=tree[root].num;
		return ;
	}
	int mid=(tree[root].left+tree[root].right)>>1;
	if(pos>mid)
	search(root*2+1,pos,result);
	else 
	search(root*2,pos,result);
	result+=tree[root].num;
}
int main()
{
	int n,k;
	scanf("%d %d",&k,&n);
	build(1,n,1);
	for(int i=0;i<k;i++)
	{
		char str[20];
		scanf("%s",str);
		if(str[0]=='A')
		{
			int a,b,x;
			scanf("%d %d %d",&a,&b,&x);
			update(a,b,x,1);
		}
		if(str[0]=='Q')
		{
			int pos;
			long long result=0;
			scanf("%d",&pos);
			search(1,pos,result);
			printf("%d\n",result);
		}
	}
	return 0;
}



nyoj 116 士兵杀敌(四)(线段树区间更新和单点查询)

标签:

原文地址:http://blog.csdn.net/su20145104009/article/details/51149635

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!