Replace and Keep Sorted
题目描述
Given a positive integer kkk , two arrays are called kkk -similar if:
- they are strictly increasing;
- they have the same length;
- all their elements are positive integers between 111 and kkk (inclusive);
- they differ in exactly one position.
You are given an integer kkk , a strictly increasing array aaa and qqq queries. For each query, you are given two integers li≤ril_i \leq r_ili≤ri . Your task is to find how many arrays $ b $ exist, such that bbb is kkk -similar to array [ali,ali+1…,ari][a_{l_i},a_{l_i+1}\ldots,a_{r_i}][ali,ali+1…,ari] .
输入格式
The first line contains three integers nnn , qqq and kkk ( 1≤n,q≤1051\leq n, q \leq 10^51≤n,q≤105 , $n\leq k \leq 10^9 $ ) — the length of array aaa , the number of queries and number kkk .
The second line contains nnn integers a1,a2,…,ana_1, a_2, \ldots,a_na1,a2,…,an ( 1≤ai≤k1 \leq a_i \leq k1≤ai≤k ). This array is strictly increasing — a1<a2<…<ana_1 < a_2 < \ldots < a_na1<a2<…<an .
Each of the following $ q $ lines contains two integers lil_ili , rir_iri ( 1≤li≤ri≤n1 \leq l_i \leq r_i \leq n1≤li≤ri≤n ).
输出格式
Print qqq lines. The iii -th of them should contain the answer to the iii -th query.
样例 #1
样例输入 #1
4 2 5
1 2 4 5
2 3
3 4
样例输出 #1
4
3
样例 #2
样例输入 #2
6 5 10
2 4 6 7 8 9
1 4
1 2
3 5
1 6
5 5
样例输出 #2
8
9
7
6
9
提示
In the first example:
In the first query there are $ 4 $ arrays that are $ 5 $ -similar to $ [2,4] $ : $ [1,4],[3,4],[2,3],[2,5] $ .
In the second query there are $ 3 $ arrays that are $ 5 $ -similar to $ [4,5] $ : $ [1,5],[2,5],[3,5] $ .
题面翻译
给定一个自然数 kkk。
我们定义两个数列是 kkk 相同的,当且仅当这两个数列长度相同,严格递增,元素都在 [1,k][1,k][1,k] 之间,且恰好存在一个数不同。
现在给出一个长度为 nnn 的严格递增的数列 AAA ,每次询问一个区间 [Li,Ri][L_i,R_i][Li,Ri] ,求出ALi,ALi+1……ARiA_{L_i},A_{L_i+1}……A_{R_i}ALi,ALi+1……ARi 这个数列有多少个与其 kkk 相同的数列。
思路:
每次只能变动原序列一个元素,且这个元素变动范围在其前后两元素之间。
位于开头的元素需要 ≥1\ge 1≥1,位于末尾的元素需要 ≤k\le k≤k,其余中间的元素 aia_iai 需要 ai−1a_{i-1}ai−1 小于 aia_iai 小于 ai+1a_{i+1}ai+1。
所以利用差分和,设差分为 d[i]=a[i]-a[i-1]
,则每个元素(非首尾元素)可以有 d[i]-1+d[i+1]-1
种可行情况
临界分析:对于首尾元素,a[1]
有 d[1]-1+a[1]-1
种可行情况,a[n]
有 d[n]-1+k-a[n]
种可行情况。
把所有可行情况加起来就可以了,算 sumsumsum 的时候用到差分和,避免重复计算超时。
代码:
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<list>
using namespace std;
const int N = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e6;
#define LL long long
int a[N] , n , t , k , num[N];
int main(){
cin >> n >> t >> k;
for(int i = 1 ; i <= n ; i++){
cin >> a[i];
}
a[0] =0 , a[n + 1] = k;
for(int i = 1 ; i <= n ; i++){
num[i] = (a[i] - 1 - a[i - 1]) + (a[i + 1] - a[i] - 1);
}
for(int i = 1 ; i <= n ; i++){
num[i] += num[i - 1];
}
while(t--){
int l , r;
cin >> l >> r;
LL ans;
if(l == r){
ans = k - 1;
}else {
ans= num[r - 1] - num[l];
ans += a[l + 1] - 2 + k - 1 - a[r - 1];
}
cout << ans << endl;
}
return 0;
}