HDU 4638 Group 莫队

 注意:这个题中得注意先要移动右指针在移动左指针。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct note
{
    int id,l,r,ans;
} q[maxn];
int block[maxn];
int mp[maxn];
int num[maxn];
int cmp1(note a,note b)
{
    if(block[a.l]<block[b.l]) return 1;
    if(block[a.l]>block[b.l]) return 0;
    return a.r<b.r;
}
int cmp2(note a,note b)
{
    return a.id<b.id;
}
int last_l,last_r;
int main()
{
    int t;
    scanf("%d",&t);
    for(int it=1; it<=t; it++)
    {
        last_l=1;
        last_r=0;
        memset(mp,0,sizeof(mp));
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
            scanf("%d",&num[i]);
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        block[0]=(int)sqrt(n);
        for(int i=1; i<=n; ++i)
            block[i]=i/block[0]+1;
        int sum=0;
        sort(q+1,q+1+n,cmp1);
        for(int i=1; i<=m; i++)
        {
            if(last_r<q[i].r)
            {
                for(int j=last_r+1; j<=q[i].r; j++)
                {
                    sum++;
                    mp[num[j]]=1;
                    if(mp[num[j]+1])
                        sum--;
                    if(mp[num[j]-1])
                        sum--;
                }
            }
            if(last_r>q[i].r)
            {
                for(int j=q[i].r+1; j<=last_r; j++)
                {
                    sum--;
                    mp[num[j]]=0;
                    if(mp[num[j]+1])
                        sum++;
                    if(mp[num[j]-1])
                        sum++;
                }
            }
            if(last_l<q[i].l)
            {
                for(int j=last_l; j<=q[i].l-1; j++)
                {
                    sum--;
                    mp[num[j]]=0;
                    if(mp[num[j]+1])
                        sum++;
                    if(mp[num[j]-1])
                        sum++;
                }
            }
            if(last_l>q[i].l)
            {
                for(int j=q[i].l; j<=last_l-1; j++)
                {
                    sum++;
                    mp[num[j]]=1;
                    if(mp[num[j]+1])
                        sum--;
                    if(mp[num[j]-1])
                        sum--;
                }
            }
            last_l=q[i].l;
            last_r=q[i].r;
            q[i].ans=sum;
        }
        sort(q+1,q+1+n,cmp2);
        for(int i=1; i<=m; i++)
            printf("%d\n",q[i].ans);
    }
}

猜你喜欢

转载自www.cnblogs.com/dongdong25800/p/11376501.html