您的位置:首页 > 其它

nyoj 108 士兵杀敌(一)

2017-04-08 13:50 260 查看


士兵杀敌(一)

题目连接:点击打开链接
时间限制: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<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int bb;
struct node
{
int l;
int r;
int num;
};
node a[3000001];
void build (int l,int r,int k)
{
a[k].l=l;
a[k].r=r;
a[k].num=0;
if(a[k].l==a[k].r)
{
//a[k].num=0;
return ;
}
else
{
int mid=(l+r)/2;
build(l,mid,2*k);
build(mid+1,r,2*k+1);
}
// return ;
}
void add(int l,int r,int c,int k)
{
if(a[k].l==l&&a[k].r==r&&l==r)
{
a[k].num+=c;
return ;
}
else
{
a[k].num+=(r-l+1)*c;
int mid=(a[k].r+a[k].l)/2;
if(l>mid)
{
add(l,r,c,2*k+1);
}
else
{
add(l,r,c,2*k);
}
}

}
int query(int l,int r,int k)
{
if(a[k].l==l&&a[k].r==r)
{
return a[k].num;
}
else
{
int mid=(a[k].r+a[k].l)/2;
if(l>mid)
{
query(l,r,2*k+1);
}
else if(r<=mid)
{
query(l,r,2*k);
}
else
{
return query(l,mid,2*k)+query(mid+1,r,2*k+1);
}

}

}
int main()
{
//int t;
//cin>>t;
//while(t--)
//{
int n,m,a,b;
cin>>n>>m;
build(1,n,1);
for(int i=1;i<=n;i++)
{
cin>>bb;
add(i,i,bb,1);
}
for(int i=1;i<=m;i++)
{
cin>>a>>b;
cout<<query(a,b,1)<<endl;
}
//}
return 0;
}
看了大牛代码发现,直接用一个数组记录下总和不就行了吗!!! 

ac代码

 
#include <cstdio>
#include <cstring>

using namespace std;
const int maxn = 1e6;

int b[maxn + 5];
int a[maxn + 5];

int main()

{
    int n,m;
    scanf("%d%d",&n,&m);
    //printf("%d %d\n",n,m);
    for(int i = 1;i <= n;++i){
        scanf("%d",&a[i]);
    }
    for(int i = 1;i <= n;++i)
    {
        b[i] = b[i - 1] + a[i];
    }
    while(m--)
    {
        int c,d;
        scanf("%d%d",&c,&d);
        if(c > d)
        {
            int t = c;
            c = d;
            d = t;
        }
        printf("%d\n",b[d] - b[c] + a[c]);
    }
    return 0;
}//用时184ms


ac代码


#include <cstdio>
#include <cstring>

using namespace std;
const int maxn = 1e6;

int b[maxn + 5];
int a[maxn + 5];

int main()

{
int n,m;
scanf("%d%d",&n,&m);
//printf("%d %d\n",n,m);
for(int i = 1;i <= n;++i){
scanf("%d",&a[i]);
}
for(int i = 1;i <= n;++i)
{
b[i] = b[i - 1] + a[i];
}
while(m--)
{
int c,d;
scanf("%d%d",&c,&d);
if(c > d)
{
int t = c;
c = d;
d = t;
}
printf("%d\n",b[d] - b[c] + a[c]);
}
return 0;
}//用时384。
//为何我觉得这两位大牛代码第二个更快事实却相反?




用树状数组做


#include <cstdio>

const int maxn = 1e6;

int a[maxn + 5];
int c[maxn + 5];
int n,m;
int lowbit(int n)
{
return n&(-n);
}
void add(int k,int num)

{
while(k <= n)
{
c[k] += num;
k += lowbit(k);
}
}

int query(int k)

{
int sum = 0;
while(k)
{
sum += c[k];
k -= lowbit(k);
}
return sum;
}
int main()

{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++i){
scanf("%d",&a[i]);
add(i,a[i]);
}
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x > y)
{
int t = x;
x = y;
y = t;
}
printf("%d\n",query(y) - query(x - 1));
}
return 0;
}//用时604


          









                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  简单