士兵杀敌(四)

士兵杀敌(四)

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

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



#include<stdio.h> #include<string.h> #define N 1000010 int c[N],m; int lowbit(int x) { return x&(-x); } inline int getSum(int pos) { int sum=0; while(pos<=m) { sum+=c[pos]; pos+=lowbit(pos); } return sum; } void update(int a,int d) { while(a>0) { c[a]+=d; a-=lowbit(a); } } int main() { // freopen("in.txt","r",stdin); char ch[10]; int t,a,b,d; //a,b,c分别表示从第a个人到第b个人杀敌获得军功d分 scanf("%d%d",&t,&m); memset(c,0,sizeof(c)); while(t--) { getchar(); scanf("%s",ch); if(ch[0]=='Q') { scanf("%d",&a); printf("%d\n",getSum(a)); } else { scanf("%d%d%d",&a,&b,&d); update(b,d); update(a-1,-d); } } return 0; } //开始提交时老是超时,但就是不知道怎么优化,无奈之下百度了一下,终于明白了!只有一句话:树状数组是呈线性的,
//  能真正理解这名话就能做出来了!

  

posted @ 2013-03-17 17:04  YaLing  阅读(172)  评论(0编辑  收藏  举报