hdu4638Group

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

求某一区间所包含的连续的段 对于乱序的数 到了i这个数所包含的段数 首先把这个数看作单独的段 再看一下前面是否出现了它的朋友 若出现了就说明前面已经加过这样单独的段了 就把前面的更新掉-1 这样始终保证一个段的最后一个值记录着这是第几个段 从左到右扫描一遍 离线处理后 这样用树状数组或者线段树进行区间求和就可以了

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 #define N 100010

 7 using namespace std;

 8 #define lowbit(x) (x&(-x))

 9 int p[N],a[N],re[N],ans[N],n;

10 struct node

11 {

12     int l,r,id;

13 }q[N];

14 bool cmp(node a,node b)

15 {

16     return a.r<b.r;

17 }

18 void add(int x,int da)

19 {

20     while(x<=n)

21     {

22         re[x]+=da;

23         x+=lowbit(x);

24     }

25 }

26 int getsum(int x)

27 {

28     int s=0;

29     while(x)

30     {

31         s+=re[x];

32         x-=lowbit(x);

33     }

34     return s;

35 }

36 int main()

37 {

38     int i,j,m,t;

39     cin>>t;

40     while(t--)

41     {

42         scanf("%d%d",&n,&m);

43         memset(re,0,sizeof(re));

44         for(i = 1; i <= n ; i++)

45         {

46             scanf("%d",&a[i]);

47             p[a[i]] = i;

48         }

49         for(i = 1; i <= m ;i++)

50         {

51             scanf("%d%d",&q[i].l,&q[i].r);

52             q[i].id = i;

53         }

54         sort(q+1,q+m+1,cmp);

55         j = 1;

56         for(i = 1 ; i <= n ;i++)

57         {

58             add(i,1);

59             if(a[i]<n&&p[a[i]+1]<i)

60             add(p[a[i]+1],-1);

61             if(a[i]>1&&p[a[i]-1]<i)

62             add(p[a[i]-1],-1);

63             while(j<=m&&q[j].r==i)

64             {

65                 int x = getsum(q[j].r);

66                 int y = getsum(q[j].l-1);

67                 ans[q[j].id] =x - y;

68                 j++;

69             }

70         }

71         for(i = 1; i <= m ; i++)

72         printf("%d\n",ans[i]);

73     }

74     return 0;

75 }
View Code

 

你可能感兴趣的:(group)