链接:https://ac.nowcoder.com/acm/contest/917/H
来源:牛客网
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
题目背景
把一张纸对折100次就和珠穆朗玛峰一样高了哦
——syh
题目描述
水宝宝某天突发奇想,在纸上写了这样一个问题:
给一个a数组,求∑∞i=1get(l,r,i)⋅∑∞i=1get(l1,r1,i)∑i=1∞get(l,r,i)⋅∑i=1∞get(l1,r1,i)
,其中get(l,r,x)表示求a[l]~a[r]中x出现了几次,他很快推出了规律,
但正当他把这道题录入电脑是发现作为一个蒟蒻的他不会打latex也没找到数学符号(主要是懒),
所以他省略了那个∑∑式子,于是,题面变为了求get(l,r,x)*get(l1,r1,x)的值了.
为了防数据过大,你要对20180623取模
注:本系列题不按难度排序哦
输入描述:
第一行一个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<=1051<=n,m<=105;1<=l,r,l1,r1<=105;a[i]≤10000,x≤100000;a[i]≤10000,x≤100000
提示:20180623不是质数
刚开始开了二维数组保存每一个数的数量,后来发现开不了这么大,赛后看别人代码,这也太神了吧!分块只听过,还没具体用过,一直以为只有莫队才会涉及分块,可现在看来,分块的形式也太多了吧,我目前了解的已经有三种方式了,分块即灵活又优美暴力。学到了学到了。
将每个数 出现的位置i 放在自己的vector【x】数组上,然后每次二分查找即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10l;
const ll mod=20180623;
int n,m;
vector<int>vec[maxn];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
int x;
cin>>x;
vec[x].push_back(i);
}
while(m--){
int l1,r1,l2,r2,x;
cin>>l1>>r1>>l2>>r2>>x;
if(l1>r1)swap(l1,r1);
if(l2>r2)swap(l2,r2);
ll pos1=upper_bound(vec[x].begin(),vec[x].end(),r1)-lower_bound(vec[x].begin(),vec[x].end(),l1);
cout<<pos1%mod<<endl;
ll pos2=upper_bound(vec[x].begin(),vec[x].end(),r2)-lower_bound(vec[x].begin(),vec[x].end(),l2);
cout<<pos2%mod<<endl;
cout<<(pos1*pos2)%mod<<endl;
}
return 0;
}