数据结构题

原题题址

题目描述

水宝宝某天突发奇想,在纸上写了这样一个问题:

给一个a数组,求∑∞i=1get(l,r,i)⋅∑∞i=1get(l1,r1,i)

,其中get(l,r,x)表示求a[l]~a[r]中x出现了几次,他很快推出了规律,

但正当他把这道题录入电脑是发现作为一个蒟蒻的他不会打latex也没找到数学符号(主要是懒),

所以他省略了那个∑

式子,于是,题面变为了求get(l,r,x)*get(l1,r1,x)的值了. 为了防数据过大,你要对20180623取模

不保证l<r,l1<r1,遇到这种情况,请先交换一下

输入描述:

第一行一个n,m 接下来一行n个数表示a[i] 接下来m行,每行l,r,l1,r1,x,表示求get(l,r,x)*get(l1,r1,x)

输出描述:

3×m行,先输出get(l,r,x),再输出get(l1,r1,x),再输出get(l,r,x)*get(l1,r1,x)

示例1

输入

5 1
2 2 2 2 2
1 5 1 3 2

输出

5
3
15

说明

对于所有数据1<=n,m<=105;1<=l,r,l1,r1<=105

;a[i]≤10000,x≤100000

提示:20180623不是质数

这题区间排序+二分可以做模板。
首先我们创建vector数组,vector[i]存依次i的出现位置,由于依次输入,那么vector内必定有序,利用lower_bound和upper_bound计算区间内x的个数即可。

#include"iostream"
#include"cstdio"
#include"vector"
#include"algorithm"
#define mod 20180623
using namespace std;
typedef long long ll;
void swap(int &a,int &b){
ll t = a+b;
b = max(a,b);
a = t - b;
}
vector <int> V[100000+5];
int main(){
    int N,M,a;
    scanf("%d%d",&N,&M);
    for(int i = 1;i <= N;i++){
     scanf("%d",&a);
      V[a].push_back(i);
    }
    for(int i = 0;i < M;i++){
    int l,r,l1,r1,tag;
        scanf("%d",&l);
        scanf("%d",&r);
        scanf("%d",&l1);
        scanf("%d",&r1);
        scanf("%d",&tag);
    swap(l,r);
    swap(l1,r1);
    int sum1 = upper_bound(V[tag].begin(),V[tag].end(),r) - lower_bound(V[tag].begin(),V[tag].end(),l);
    int sum2 = upper_bound(V[tag].begin(),V[tag].end(),r1) - lower_bound(V[tag].begin(),V[tag].end(),l1);
    printf("%d\n",sum1%mod);
     printf("%d\n",sum2%mod);
    printf("%d\n",((sum1%mod)*(sum2%mod))%mod);
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值