HDU 4638 Group 離線莫隊
阿新 • • 發佈:2018-11-19
/** HDU 4638 Group 莫隊 連結:http://acm.hdu.edu.cn/showproblem.php?pid=4638 題意:區間連續數字的塊數; 離線莫隊;判斷當前數字移去或新增時對當前區間該數字左右端點的影響; ***********tricks*********** 手寫排序差評; */ #include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e5+7; int n,q,blo,s[maxn],pos[maxn]; struct node{ int l,r,id; bool operator <(const node &a)const{ return pos[l]<pos[a.l]||(pos[l]==pos[a.l]&&r<a.r); } }a[maxn]; int ans[maxn]; int num[maxn]; int main(){ int t;scanf("%d",&t); while(t--){ scanf("%d %d",&n,&q); blo=(int)sqrt(n*1.0); for(int i=1;i<=n;i++) pos[i]=(i-1)/blo+1; for(int i=1;i<=n;i++) scanf("%d",&s[i]); for(int i=1;i<=q;i++){ scanf("%d %d",&a[i].l,&a[i].r); a[i].id=i; } sort(a+1,a+1+q); int l=1,r=0,ret=0; memset(num,0,sizeof(num)); for(int i=1;i<=q;i++){ while(r<a[i].r){ r++; num[s[r]]=1; if(num[s[r]-1]==1&&num[s[r]+1]==1) ret--; else if(num[s[r]-1]==0&&num[s[r]+1]==0) ret++; } while(r>a[i].r){ num[s[r]]=0; if(num[s[r]-1]==1&&num[s[r]+1]==1) ret++; else if(num[s[r]-1]==0&&num[s[r]+1]==0) ret--; r--; } while(l<a[i].l){ num[s[l]]=0; if(num[s[l]-1]==1&&num[s[l]+1]==1) ret++; else if(num[s[l]-1]==0&&num[s[l]+1]==0) ret--; l++; } while(l>a[i].l){ l--; num[s[l]]=1; if(num[s[l]-1]==1&&num[s[l]+1]==1) ret--; else if(num[s[l]-1]==0&&num[s[l]+1]==0) ret++; } ans[a[i].id]=ret; } for(int i=1;i<=q;i++) printf("%d\n",ans[i]); } return 0; } /* 2 5 4 3 1 2 5 4 1 5 2 4 2 5 3 4 7 6 2 7 3 6 5 1 4 2 4 2 7 3 6 1 5 3 7 2 5 */