士兵杀敌(一)
时间限制:
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<string.h>
int x[1000005];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(x,0,sizeof(x));//注意清零
for(int i=1;i<=n;++i)
{
scanf("%d",x+i);
x[i]+=x[i-1];//没一个位置保存的都是不大于这一位的所有的项的和
}
for(int i=0;i<m;++i)
{
int l,r,sum;
scanf("%d%d",&l,&r);
sum=x[r]-x[l-1];//想想为什么
printf("%d\n",sum);
}
}
return 0;
}
2015年11月8号:
刚学了线段树,就拿来试试看,竟然a掉了,虽然比之前的程序要耗更多的内存和时间,哈哈,慢慢学线段树吧!
区间求和,查询函数按自己理解的写的,应该没有模板的写的精炼....
继续努力!
#include<stdio.h>
int n,m,sum,x[4000005],a,b;
void build(int rt,int l,int r)
{
if(l==r)
{
scanf("%d",&x[rt]);
return;
}
int mid=(l+r)>>1,tp=rt<<1;
build(tp,l,mid);build(tp|1,mid+1,r);
x[rt]=x[tp]+x[tp|1];
}
void find(int rt,int l,int r)
{
if(l>=a&&r<=b)
{
sum+=x[rt];
return;
}
if(l==r||l>b||r<a)//没有有效数据的区间
{
return;
}
int mid=(l+r)>>1,tp=rt<<1;
find(tp,l,mid);//否则左右递归求解
find(tp|1,mid+1,r);
}
int main()
{
// freopen("shuju.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
build(1,1,n);//建树
for(int i=0;i<m;++i)
{
sum=0;
scanf("%d%d",&a,&b);
find(1,1,n);//查找
printf("%d\n",sum);
}
}
return 0;
}