给你一个1~N的排列,问区间[L, R] 之间有多少段连续的数。比如区间里有3、1、2、5、6,这五个数,那么就有3、1、2和5、6这两段。
询问一个区间的时候,可以一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已经添加在内,如果两个都在,则总段数减1,如果两个都不在,总段数加1,其他情况总段数不变了。
const int maxn = 100100 ;
struct Q{
int l , r , id , p ;
friend bool operator < (const Q A , const Q B){
if(A.p == B.p) return A.r < B.r ;
else return A.p < B.p ;
}
}q[maxn + 8] ;
int a[maxn + 8] ;
int ans[maxn + 8] ;
int L , R , sum ;
bool vis[maxn + 8] ;
void add(int x){
vis[x] = 1 ;
if(vis[x-1] && vis[x+1]) sum-- ;
else if(!vis[x-1] && !vis[x+1]) sum++ ;
}
void del(int x){
vis[x] = 0 ;
if(vis[x-1] && vis[x+1]) sum++ ;
else if(!vis[x-1] && !vis[x+1]) sum-- ;
}
int ask(int l , int r , int id){
int i ;
if(id == 0){
sum = 0 ;
for(i = l ; i <= r ; i++) add(a[i]) ;
L = l , R = r ;
return sum ;
}
for(i = l ; i < L ; i++) add(a[i]) ;
for(i = R+1 ; i <= r ; i++) add(a[i]) ;
for(i = L ; i < l ; i++) del(a[i]) ;
for(i = r+1 ; i <= R ; i++) del(a[i]) ;
L = l , R = r ;
return sum ;
}
int main(){
int i , j , n , m , t ;
int blocksize ;
cin>>t ;
while(t--){
scanf("%d%d" , &n , &m) ;
for(i = 1 ; i <= n ; i++) scanf("%d" ,&a[i]) ;
blocksize = sqrt(0.5 + n) ;
for(i = 0 ; i < m ; i++){
scanf("%d%d" , &q[i].l , &q[i].r) ;
q[i].id = i ;
q[i].p = q[i].l / blocksize ;
}
memset(vis , 0 , sizeof(vis)) ;
sort(q , q+m) ;
for(i = 0 ; i < m ; i++)
ans[q[i].id] = ask(q[i].l , q[i].r , i) ;
for(i = 0 ; i < m ; i++) printf("%d\n" , ans[i]) ;
}
return 0 ;
}
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include <stdio.h>
#include <algorithm>
#include <map>
#include <math.h>
typedef long long LL ;
const int N = 100008 ;
int n ;
namespace BIT{
int val[N] ;
int lowbit(int x){
return x & (-x) ;
}
void add(int idx , int c){
for(; idx <=n ; idx += lowbit(idx)) val[idx] += c ;
}
int sum(int idx){
int res = 0 ;
for(; idx ; idx -= lowbit(idx)) res += val[idx] ;
return res ;
}
int sum(int l , int r){
return sum(r) - sum(l-1) ;
}
void clear(){
std::fill(val , val + 1 + n , 0) ;
}
}
int position[N] , a[N] , vis[N] , res[N] ;
struct Query{
int Lf , Rt , idx ;
friend bool operator < (const Query &a , const Query &b){
return a.Rt < b.Rt ;
}
};
Query q[N] ;
int main(){
std::ios::sync_with_stdio(false) ;
int t , m ;
scanf("%d" , &t) ;
while(t--){
scanf("%d%d" , &n , &m) ;
for(int i = 1 ; i <= n ; i++){
scanf("%d" , &a[i]) ;
position[a[i]] = i ;
}
for(int i = 0 ; i < m ; i++){
scanf("%d%d" , &q[i].Lf , &q[i].Rt ) ;
q[i].idx = i ;
}
std::sort(q , q + m) ;
BIT::clear() ;
std::fill(vis , vis + 1 + n , 0) ;
int idx = 0 ;
for(int i = 1 ; i <= n ; i++){
vis[a[i]] = 1 ;
BIT::add(i , 1) ;
if(vis[a[i]-1]) BIT::add(position[a[i]-1] , -1) ;
if(vis[a[i]+1]) BIT::add(position[a[i]+1] , -1) ;
while(idx < m && q[idx].Rt == i){
res[q[idx].idx] = BIT::sum(q[idx].Lf, q[idx].Rt) ;
idx++ ;
}
}
for(int i = 0 ; i < m ; i++) printf("%d\n" , res[i]) ;
}
return 0 ;
}