HDU 4638 Group(莫队算法)

来源:互联网 发布:js弹出自定义div窗口 编辑:程序博客网 时间:2024/05/23 01:57





http://acm.hdu.edu.cn/showproblem.php?pid=4638






题目大意:

N 个数字   m次询问   每次询问一个区间    问区间内连续的数字有多少组





分析:

莫队算法就可以    

设置一个flag数组   


add时将 flag[a[index]]  设置为 1    表示加入元素a[index]    

如果元素a[index]   两侧的值都没有在之前组内   则a[index]自成一组  ans++ 

如果元素a[index]   两侧的值都在之前组内   则a[index]起桥梁作用链接两组  ans--

其他情况可分到任意一组   ans不变


add时将 flag[a[index]]  设置为 0    表示删除元素a[index]    

如果元素a[index]   两侧的值都没有在之前组内   则a[index]自成一组  删掉后  ans--

如果元素a[index]   两侧的值都在之前组内   则a[index]起桥梁作用链接两组  删掉后   桥梁断裂   ans++

其他情况是删除组中元素    ans不变






AC代码:

#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <math.h>#include <vector>#include <stack>#include <queue>#include <map>#include <set>#include<list>#include <bitset>#include <climits>#include <algorithm>#define gcd(a,b) __gcd(a,b)#define mset(a,n) memset(a,n,sizeof(a))#define FINfreopen("input.txt","r",stdin)#define FOUT freopen("output.txt","w",stdout)typedef long long LL;const LL mod=1e9+7;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);using namespace std;int a[100005];int pos[100005];int flag[100005];int ans;int maxa,maxd,mina,mind;struct node{    int l,r;    int index;    int ans;}Q[100005];bool cmp1(node x,node y){    return pos[x.l]==pos[y.l]?x.r<y.r:x.l<y.l;}bool cmp2(node x,node y){    return x.index<y.index;}void add(int index){    flag[a[index]]=1;    if (!(flag[a[index]+1]||flag[a[index]-1])) ans++;    else if (flag[a[index]+1]&&flag[a[index]-1]) ans--;}void del(int index){    flag[a[index]]=0;    if (!(flag[a[index]+1]||flag[a[index]-1])) ans--;    else if (flag[a[index]+1]&&flag[a[index]-1]) ans++;}int main (){    int t;    scanf ("%d",&t);    while (t--){        int n,m;        scanf ("%d%d",&n,&m);        mset(a,0);mset(Q,0);mset(flag,0);        int div=sqrt(n);        for (int i=1;i<=n;i++) scanf ("%d",&a[i]);        for (int i=1;i<=m;i++) scanf ("%d%d",&Q[i].l,&Q[i].r),Q[i].index=i,pos[i]=(i-1)/div+1;        sort(Q+1,Q+m+1,cmp1);        int ll=1,rr=0;        ans=0;        for (int i=1;i<=m;i++){            while (rr<Q[i].r) rr++,add(rr);            while (rr>Q[i].r) del(rr),rr--;            while (ll<Q[i].l) del(ll),ll++;            while (ll>Q[i].l) ll--,add(ll);            Q[i].ans=ans;        }        sort(Q+1,Q+m+1,cmp2);        for (int i=1;i<=m;i++) printf ("%d\n",Q[i].ans);    }    return 0;}


原创粉丝点击