莫队算法基础题,题目看懂就能做出来
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define MAXN 100005 #define ll long long struct Query{ int L,R,id; }q[MAXN]; int s,vis[MAXN],id[MAXN]; ll ans[MAXN]; ll res; bool cmp(Query a,Query b){ if(a.L/s == b.L/s) return a.R<b.R; return a.L/s < b.L/s; } void add(int idx){//加入编号为idx的点 if(vis[idx-1] && vis[idx+1]) res--;//如果两边都是连续的,那么组可以减一 else if(!vis[idx-1] && !vis[idx+1]) res++;//如果两边都是断开的,那么加入该点可以使组加一 vis[idx]=1; } void dec(int idx){ if(vis[idx-1] && vis[idx+1]) res++; else if(!vis[idx-1] && !vis[idx+1]) res--; vis[idx]=0; } int main(){ int n,m,t; scanf("%d",&t); while(t--){ memset(vis,0,sizeof vis); scanf("%d%d",&n,&m); s=(int)sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&id[i]); for(int i=0;i<m;i++){ scanf("%d%d",&q[i].L,&q[i].R); q[i].id=i; } sort(q,q+m,cmp); int L=1,R=0; res=0; for(int i=0;i<m;i++){ while(R<q[i].R){ R++; add(id[R]); } while(R>q[i].R){ dec(id[R]); R--; } while(L<q[i].L){ dec(id[L]); L++; } while(L>q[i].L){ L--; add(id[L]); } ans[q[i].id]=res; } for(int i=0;i<m;i++) printf("%d ",ans[i]); } return 0; }