Group HDU - 4638

//如果a[i]-1 和 a[i] + 1都没有维护过的话,那么就是多一个新串 
//如果 a[i] - 1和a[i] + 1 有一个被维护过了,那么接上就好
//如果 a[i] -1 和a[i] + 1 都被维护过了,那么把两个合成一个,就少一个串 
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
struct node{
    int L,R,id;
} ask[maxn];
int ans[maxn];
int a[maxn],num[maxn];//从1开始计数
int n,m,siz,temp;//n个数,m个询问,块的大小
bool cmp(node a,node b) {//分块排序 
    if(a.L/siz!=b.L/siz) 
        return a.L/siz<b.L/siz;
    else return a.R<b.R;
}
void sub(int pos) {
    int x=a[pos];
    num[x]=0;
    if(num[x-1]==0&&num[x+1]==0) 
        temp--;
    if(num[x-1]==1&&num[x+1]==1) 
        temp++;
}
void add(int pos) {
    int x=a[pos];
    num[x]=1;
    if(num[x-1]==0&&num[x+1]==0) 
        temp++;
    if(num[x-1]==1&&num[x+1]==1) 
        temp--;
}
void solve() {
    temp=0;
    memset(num,0,sizeof num);
    int L=1,R=0;
    for(int i=1; i<=m; i++) {
        while(R<ask[i].R) {
            R++;
            add(R);
        }
        while(R>ask[i].R) {
            sub(R);
            R--;
        }
        while(L<ask[i].L) {
            sub(L);
            L++;
        }
        while(L>ask[i].L) {
            L--;
            add(L);
        }
        ans[ask[i].id]=temp;
    }
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) 
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        for(int i=1; i<=m; i++) {
            ask[i].id=i;
            scanf("%d%d",&ask[i].L,&ask[i].R);
        }
        siz=sqrt(n);
        sort(ask+1,ask+m+1,cmp);
        solve();
        for(int i=1; i<=m; i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12380360.html