NYOJ228士兵杀敌(五)

题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=228

题意很简单,就不说了。这个题目如果用线段树和树状数组都不好过,甚至过不了,因为不是在线问的,所以用在这里很浪费。这个题目可以用数组直接来做。

解题思路:首先数组初始化为0,如果第i到第j个人平均杀敌k,那么就让数组shu[i]加k,而shu[j+1]减k。更新输入结束后,用以个变量value=0,依次加shu[i](0<=i<=n+1),那么得到的value就是第i个士兵的杀敌数量,顺便计算出前i项的和,那么当求第i个士兵到第j各士兵的时候,就可以用shu[j]-shu[i-1]得到结果了,代码1就是 这个思路写的。还有一种解题思路是先循环计算每个士兵的杀敌数,然后再算前i项的和(其实这两个是可以一起计算的),这样写可能容易理解一点吧,代码2是按这个思路写的。

代码1:

 
#include <iostream>
#include <stdio.h>
#define N 2000005
#define Mod 10003
using namespace std;
int  shu[N]={0};
int main()
{
    int n,m,que,i,x,y,value;
    scanf("%d%d%d",&n,&m,&que);
    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&x,&y,&value); 
        shu[x]+=value;
		shu[y+1]-=value;
    }
	n+=1;
	value=0;
    for(i=0;i<=n;i++)
    {
        value+=shu[i];
        shu[i]=(value+shu[i-1])%Mod;
    }
    for(i=0;i<que;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",(shu[y]-shu[x-1]+Mod)%Mod);
    }
    return 0;
}
        




代码2:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define N 1000005
#define Mod 10003
using namespace std;

int v[N];
int main()
{
    int n,c,q,l,r,cnt;
    scanf("%d%d%d",&n,&c,&q);
    int e=0;
    for(int i=0;i<c;i++)
    {
        scanf("%d%d%d",&l,&r,&cnt);
        if(cnt == 0) continue;
        v[l-1] -= cnt;
        v[r] += cnt;
        if(e<r) e=r;
    }
    for(int i=e-1; i>=0; --i)
        v[i] += v[i+1];
    v[0]=0;
    for(int i=1; i<=n; i++)
    {
         v[i] = (v[i]+v[i-1])%Mod;
    }
    for(int i=0;i<q;i++)
    {
        scanf("%d%d",&l, &r);
        printf("%d\n",(v[r]-v[l-1]+Mod)%Mod);
    }
    return 0;
}



你可能感兴趣的:(NYOJ228士兵杀敌(五))