其实自己是当错题单来看的,哈哈!
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
小蓝获得了一个长度为 n的数组:A1,A2,...,AnA_1,A_2,...,A_nA1,A2,...,An。
小红对小灰灰提出了 mmm 个询问,第 iii 个询问给出两个参数 li,ril_i, r_ili,ri 代表小红截取了原数组的 Ali,Ali+1,...,AriA_{l_i}, A_{l_i + 1}, ..., A_{r_i}Ali,Ali+1,...,Ari 部分。
对于每个询问,小灰灰想知道小红截取出的数组有多少段。
一个长度为 sss 的数组 B1,B2,...,BsB_1, B_2, ..., B_sB1,B2,...,Bs,其段数被定义为最小的 kkk 使得将数组划分成连续的 kkk 段后,每个元素都属于某一段,且每段数组中的元素种类应该全部相同。
输入描述:
输入第一行包含两个空格分隔的整数 nnn,mmm 分别代表数组长度和询问个数。 接下来一行输入 nnn 个空格分隔的整数分别代表:A1,A2,...,AnA_1, A_2, ..., A_nA1,A2,...,An。 接下来 mmm 行,第 iii 行包含两个空格分隔的整数 li ril_i\ r_ili ri 代表第 iii 个询问给出的两个参数。 保证: 1≤n,m≤2×1051 \le n,m \le 2\times10^51≤n,m≤2×105 1≤Ai≤1061 \le A_i \le 10^61≤Ai≤106 1≤li≤ri≤n1\le l_i\le r_i\le n1≤li≤ri≤n
输出描述:
输出共 m行,第 i 行代表第 i个询问的答案。
示例1
输入
6 4 2 2 3 1 3 3 1 3 2 5 2 2 4 6
输出
2 4 1 2
这个题我当初写的时候是用遍历的方法无脑写的,结果发现超时了,最后去哔哩哔哩牛客官方看完讲解才懂。
题解:这道题的关键点是利用前缀和思想(提前遍历搞好前缀和数组)可以降低时间复杂度。设前缀和数组为s[i],则s[i]=s[i-1]+X,s[i]的数值为从第1个元素到第i个元素的元素之和。
//这个题实打实用到的是前缀和思想
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N],cnt[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
if(a[i]!=a[i-1])
{
cnt[i]=cnt[i-1]+1;
}
else
{
cnt[i]=cnt[i-1]+0;
}
}
int l,r;
while(m--)
{
cin>>l>>r;
cout<<(cnt[r]-cnt[l]+1)<<endl;
}
return 0;
}