Breed Counting(水?)

本文介绍了一种用于快速计算特定区间内不同品种奶牛数量的算法。通过维护三种奶牛(Holstein、Guernsey 和 Jersey)的前缀和数组,该方法能够在常数时间内响应任意区间内的查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2386: Breed Counting

时间限制: 1 Sec   内存限制: 64 MB
提交: 81   解决: 31
[ 提交][ 状态][ 讨论版]

题目描述

Farmer John's N cows, conveniently numbered 1…N, are all standing in a row (they seem to do so often that it now takes very little prompting from Farmer John to line them up). Each cow has a breed ID: 1 for Holsteins, 2 for Guernseys, and 3 for Jerseys. Farmer John would like your help counting the number of cows of each breed that lie within certain intervals of the ordering. 

输入

The first line of input contains N and Q (1≤N≤100,000, 1≤Q≤100,000).

The next N  lines contain an integer that is either 1, 2, or 3, giving the breed ID of a single cow in the ordering.

The next Q  lines describe a query in the form of two integers a,b (a≤b). 

输出

For each of the Q queries (a,b), print a line containing three numbers: the number of cows numbered a…b that are Holsteins (breed 1), Guernseys (breed 2), and Jerseys (breed 3). 

样例输入

6 3
2
1
1
3
2
1
1 6
3 3
2 4

样例输出

3 2 1
1 0 0
2 0 1


比赛时直接用线段树开了3个数组做的。

其实还有更好的方法。

同样是开3个数组。

通过记录每个位置的前缀和,查询的时候直接输出 num[r] - num[l-1],就行了,就是这一段的和。 赞一个给力的孙学弟

源代码

#include<cstring>
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 100005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mem(a,x) memset(a,x,sizeof(a))
int num1[maxn];
int num2[maxn];
int num3[maxn];
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        int tmp;
        mem(num1,0);
        mem(num2,0);
        mem(num3,0);
        for(int i=1;i<=n;i++){
            num1[i] += num1[i-1];
            num2[i] += num2[i-1];
            num3[i] += num3[i-1];
            scanf("%d",&tmp);
            if(tmp == 1) num1[i]++;
            if(tmp == 2) num2[i]++;
            if(tmp == 3) num3[i]++;
        }
        while(m--){
            int a,b;scanf("%d%d",&a,&b);
            printf("%d ",num1[b] - num1[a-1]);
            printf("%d ",num2[b] - num2[a-1]);
            printf("%d\n",num3[b] - num3[a-1]);
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值