0
点赞
收藏
分享

微信扫一扫

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


  • 题目123
  • ​​题目信息​​
  • ​​运行结果​​
  • ​​本题排行​​
  • ​​讨论区​​

士兵杀敌(四)


2000 ms  |  内存限制: 65535


南将军麾下有百万精兵,现已知共有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;
}



举报

相关推荐

0 条评论