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

来源:互联网 发布:冒泡排序c语言n个元素 编辑:程序博客网 时间:2024/05/19 16:20

士兵杀敌(四)

时间限制: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 10ADD 1 3 10QUERY 3ADD 2 6 50QUERY 3
样例输出
1060
来源
[张云聪]原创
上传者
张云聪

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

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

总之算是有了思路 

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;}


                                             
1 0