原题大意:
给出长度为 n 的数组,有 q 次询问,以及 k,每次询问输入l,r;表示区间l,r,要求构造一个长度相同的区间
使得构造的区间满足1.严格递增
2.有相同的长度
3.所有的元素都属于 [1,k]
4.与所询问区间只有一个位置处的元素不同 求总共可以构造多少这样的区间
输入格式
第一行包含三个整数n、q和k(1≤n,q≤105,n≤k≤109)-数组a的长度、查询次数和数量k。第二行包含n个整数a1,a2,…。,An(1≤ai≤k)。此数组严格递增-a1<a2<…。<An.。
以下q行中的每一行都包含两个整数li,ri(1≤li≤ri≤n)。
输出格式
打印Q行。它们中的第i个应该包含对第i个查询的答案。
Examples
input
4 2 5
1 2 4 5
2 3
3 4
output
4
3
input
6 5 10
2 4 6 7 8 9
1 4
1 2
3 5
1 6
5 5
output
8
9
7
6
9
首先对于答案,会等于区间内每个元素贡献之和,所以我们只需要计算区间没每一个值的贡献。
1.最左端的贡献为 a[l+1]-2,因为只能有一个值相等,所以我们可以从a[l+1]-1开始计算,又因为长度必须与原来的相等,所以贡献为a[l+1]-2
2.最右端的贡献为k-a[r-1]-1,推到过程类似与最左端
3.中间 任一贡献为a[i+1]-a[i-1]-2
对于中间任一贡献,可以使用前缀和进行统计,然后就能达到O(1)
AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+3;
int a[maxn];
ll sum[maxn];
int main(){
int n,T,k;
scanf("%d %d %d",&n,&T,&k);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=n;++i)
sum[i]=sum[i-1]+a[i+1]-a[i-1]-2;
while(T--){
ll ans=0;
int l,r;
scanf("%d %d",&l,&r);
ans+=sum[r-1]-sum[l];
ans+=k-a[r-1]-1;
ans+=a[l+1]-2;
printf("%lld\n",ans);
}
return 0;
}