HDU Group

Posted cxchanpin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU Group相关的知识,希望对你有一定的参考价值。

                                                      Group

题目:

   给出n个数。是1-n的排列。要求你每次给你一个区间求出这个区间能够被分成的小区间个数。一个不连续的数能够被分成一个小区间。t-1,t或t,t+1表示连续。

算法:

  高速做法应该是线段树。可是,我不会。

学了一个块状数组。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

const int MAXN = 100000 + 10;

struct Node{
   int l,r,id,b;

   bool operator < (const Node& rhs) const {
       if(b != rhs.b){
          return b < rhs.b;
       }
       return r < rhs.r;
   }
}query[MAXN];

int seg[MAXN];
bool vst[MAXN];
int n,m,res;
int ans[MAXN];

void cal(int x,int &l,int &r){
    int L = query[x].l, R = query[x].r;
    while(L < l){  //须要将左右区间进行放大,否则可能出现左右游标交错的情况
        --l;
        int t = seg[l];
        vst[t] = 1;
        if(vst[t-1]&&vst[t+1]) --res;
        else if(!vst[t-1]&&!vst[t+1]) ++res;
    }

    while(R > r){
        ++r;
        int t = seg[r];
        vst[t] = 1;
        if(vst[t-1]&&vst[t+1]) --res;
        else if(!vst[t-1]&&!vst[t+1]) ++res;
    }

    while(L > l){
        int t = seg[l];
        vst[t] = 0;
        if(vst[t-1]&&vst[t+1]) ++res;
        else if(!vst[t-1]&&!vst[t+1]) --res;
       ++l;
    }

    while(R < r){
        int t = seg[r];
        vst[t] = 0;
        if(vst[t-1]&&vst[t+1]) ++res;
        else if(!vst[t-1]&&!vst[t+1]) --res;
        --r;
    }
}

void solve(){
   memset(vst,0,sizeof(vst));
   sort(query,query + m);
   res = 0;
   int l = query[0].l, r = query[0].r;
   for(int i = l;i <= r;++i){
       int t = seg[i];
       vst[t] = 1;
       if(vst[t-1] && vst[t+1]) --res;
       else if(!vst[t-1]&&!vst[t+1]) ++res;
   }

   ans[query[0].id] = res;
   for(int i = 1;i < m;++i){
       ans[query[i].id] = (cal(i,l,r),res);
   }

   for(int i = 0;i < m;++i){
      printf("%d\n",ans[i]);
   }

}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);

        for(int i = 1;i <= n;++i){
            scanf("%d",&seg[i]);
        }

        int B = sqrt(1.0*n);
        for(int i = 0;i < m;++i){
            scanf("%d%d",&query[i].l,&query[i].r);
            query[i].b = query[i].l / B;
            query[i].id = i;
        }

        solve();
    }
    return 0;
}


以上是关于HDU Group的主要内容,如果未能解决你的问题,请参考以下文章

HDU Group

HDU4638:Group(线段树离线处理)

hdu 2985 The k-th Largest Group 树状数组求第K大

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

HDU3247 Resource Archiver(AC自动机+BFS+DP)

加速ddply