理解题意:连续的数分为一组,每次判断下就可以了!!
代码如下:

1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<cstring> 7 #include<vector> 8 #define ll __int64 9 #define pi acos(-1.0) 10 #define MAX 100105 11 using namespace std; 12 int R,L,an[MAX],ans[MAX],res; 13 bool vis[MAX]; 14 struct node 15 { 16 int x,y,l,p; 17 }q[MAX]; 18 bool cmp(const node &a,const node &b) 19 { 20 if(a.l==b.l) return a.y<b.y; 21 return a.l<b.l; 22 } 23 void query(int x,int y,int flag) 24 { 25 if(flag){ 26 for(int i=x;i<L;i++){ 27 vis[an[i]]=1; 28 if(vis[an[i]-1]&&vis[an[i]+1]) res--; 29 else if(!vis[an[i]-1]&&!vis[an[i]+1]) res++; 30 } 31 for(int i=R+1;i<=y;i++){ 32 vis[an[i]]=1; 33 if(vis[an[i]-1]&&vis[an[i]+1]) res--; 34 else if(!vis[an[i]-1]&&!vis[an[i]+1]) res++; 35 } 36 for(int i=L;i<x;i++){ 37 vis[an[i]]=0; 38 if(vis[an[i]-1]&&vis[an[i]+1]) res++; 39 else if(!vis[an[i]-1]&&!vis[an[i]+1]) res--; 40 } 41 for(int i=y+1;i<=R;i++){ 42 vis[an[i]]=0; 43 if(vis[an[i]-1]&&vis[an[i]+1]) res++; 44 else if(!vis[an[i]-1]&&!vis[an[i]+1]) res--; 45 } 46 } 47 else{ 48 for(int i=x;i<=y;i++){ 49 vis[an[i]]=1; 50 if(vis[an[i]-1]&&vis[an[i]+1]) res--; 51 else if(!vis[an[i]-1]&&!vis[an[i]+1]) res++; 52 } 53 } 54 L=x;R=y; 55 } 56 int main(){ 57 int n,t,i,j,m,c; 58 scanf("%d",&c); 59 while(c--){ 60 scanf("%d%d",&n,&t); 61 for(i=1;i<=n;i++) scanf("%d",&an[i]); 62 m=sqrt(1.0*n); 63 for(i=0;i<t;i++){ 64 scanf("%d%d",&q[i].x,&q[i].y); 65 q[i].l=q[i].x/m; 66 q[i].p=i; 67 } 68 sort(q,q+t,cmp); 69 res=0; 70 memset(vis,0,sizeof(vis)); 71 for(i=0;i<t;i++){ 72 query(q[i].x,q[i].y,i); 73 ans[q[i].p]=res; 74 } 75 for(i=0;i<t;i++) 76 printf("%d ",ans[i]); 77 } 78 return 0; 79 }