nyoj108士兵杀敌(一)
2014-12-11 16:11
281 查看
士兵杀敌(一)
时间限制:1000 ms | 内存限制:65535 KB难度:3
描述
南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的。
小工是南将军手下的军师,南将军现在想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧。
注意,南将军可能会问很多次问题。
输入只有一组测试数据
第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示南将军询问的次数(1<M<100000)
随后的一行是N个整数,ai表示第i号士兵杀敌数目。(0<=ai<=100)
随后的M行每行有两个整数m,n,表示南将军想知道第m号到第n号士兵的总杀敌数(1<=m,n<=N)。
输出对于每一个询问,输出总杀敌数
每个输出占一行
样例输入
5 2 1 2 3 4 5 1 3 2 4
样例输出
6 9
微吐槽,外面修门的声音让我很烦。。。
很久前就看过了简单的树状数组和线段树的一些皮毛,应该是最简单的情况了,貌似这道题目用普通的数组就可以刷掉,虽然我没有尝试。
树状数组实现:
#include <stdio.h> #include <stdlib.h> int dangdang[1000002]; int n; int fun1(int num) { return num & (-num); } void fun2(int i, int num) { int j; for(j=i; j<=n; j+=fun1(j)) { dangdang[j] += num; } } int getsum(int i) { int j; int sum = 0; for(j=i; j>0; j-=fun1(j)) { sum += dangdang[j]; } return sum; } int main() { int m; scanf("%d%d", &n, &m); int i; for(i=1; i<=n; i++) { int num; scanf("%d", &num); fun2(i, num); } for(i=1; i<=m; i++) { int a, b; scanf("%d%d", &a, &b); int sum = 0; sum = getsum(b) - getsum(a-1); printf("%d\n", sum); } return 0; }
线段树实现:
#include <cstdio> #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 1000002; int sum[maxn<<2]; void PushUP(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; //下标乘2, 乘2+1 } void build(int l,int r,int rt) { if (l == r) { scanf("%d",&sum[rt]); return ; } int m = (l + r) >> 1; // m = (l+r)/2 build(lson); //传进去l, m, rt*2 build(rson); //传进去m, 2, rt*2+1 PushUP(rt); //所谓的父节点 = 左 + 右 } int query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return sum[rt]; } int m = (l + r) >> 1; int ret = 0; if (L <= m) ret += query(L , R , lson); if (R > m) ret += query(L , R , rson); return ret; } int main() { int T , n; scanf("%d%d",&T, &n); build(1 , T , 1); while(n--) { int a, b; scanf("%d%d", &a, &b); printf("%d\n",query(a, b, 1, T, 1)); } return 0; }最优代码:
#include<cstdio> const int MAX=1000010; int sum[MAX]; int main() { int N,q,m,n; scanf("%d%d",&N,&q); for(int i=1;i<=N;++i) { scanf("%d",&sum[i]); sum[i]+=sum[i-1]; } for(int i=0;i!=q;++i) { scanf("%d%d",&m,&n); printf("%d\n",sum -sum[m-1]); } }
相关文章推荐
- NYOJ 108 士兵杀敌 (一) (树状数组&区间求和)
- nyoj 108-士兵杀敌1
- nyoj 108 士兵杀敌(一)
- nyoj-108-士兵杀敌(一)
- NYOJ【108】士兵杀敌(一)【前缀和】&&【查询】
- NYOJ 108士兵杀敌(一)
- nyoj 108-士兵杀敌1
- 士兵杀敌(一)(nyoj_108)
- NYOJ 108 士兵杀敌(一) 解题报告
- NYOJ 题目108 士兵杀敌(一)
- NYOJ-108-士兵杀敌(一)
- NYOJ 108 士兵杀敌(一)
- NYOJ 108 士兵杀敌(一)
- NYOJ 108 士兵杀敌(一)
- NYOJ 【108】士兵杀敌 一 (线段树 + 模板题)
- [NYOJ - 108] 士兵杀敌(一)(线段树)
- nyoj108士兵杀敌(一)
- NYOJ 108 士兵杀敌(一)
- NYOJ-108士兵杀敌(一)
- nyoj108士兵杀敌