【分块】 HDU 4638 Group

通道

题意:区间[L, R] 之间排序后有多少段连续的数

思路:一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已经添加在内,如果两个都在,则总段数减1,如果两个都不在,总段数加1,其他情况总段数不变

代码:

分块、

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;

#define N 100100

bool vis[N];
int a[N], n, m, all, L, R, ans[N];

struct node {
    int l, r, b, id;
    bool operator<(const node &x)const{
        if (b == x.b) return r < x.r;
        return b < x.b;
    }
} q[N];

void query(int x, int y, int flag) {
    if (flag != 0) {
        for (int i=x; i<L; i++) {
            vis[a[i]] = true;
            if (vis[a[i]-1] && vis[a[i]+1]) all--;
            else if (!vis[a[i]-1] && !vis[a[i]+1]) all++;
        }
        for (int i=R+1; i<=y; i++) {
            vis[a[i]] = true;
            if (vis[a[i]-1] && vis[a[i]+1]) all--;
            else if (!vis[a[i]-1] && !vis[a[i]+1]) all++;
        }
        for (int i=L; i<x; i++) {
            vis[a[i]] = false;
            if (vis[a[i]-1] && vis[a[i]+1]) all++;
            else if (!vis[a[i]-1] && !vis[a[i]+1]) all--;
        }
        for (int i=y+1; i<=R; i++) {
            vis[a[i]] = false;
            if (vis[a[i]-1] && vis[a[i]+1]) all++;
            else if (!vis[a[i]-1] && !vis[a[i]+1]) all--;
        }
    } else {
        all = 0;
        for (int i=x; i<=y; i++) {
            vis[a[i]] = true;
            if (vis[a[i]-1] && vis[a[i]+1]) all--;
            else if (!vis[a[i]-1] && !vis[a[i]+1]) all++;
        }
    }
    L = x, R = y;
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d", &n, &m);
        int block_size = sqrt(n);
        for (int i=1; i<=n; i++)  scanf("%d", &a[i]);
        for (int i=0; i<m; i++) {
            scanf("%d%d", &q[i].l, &q[i].r);
            q[i].b = q[i].l / block_size;
            q[i].id = i;
        }
        sort(q, q+m);
        memset(vis, false, sizeof(vis));
        for (int i=0; i<m; i++) {
            query(q[i].l, q[i].r, i);
            ans[q[i].id] = all;
        }
        for (int i=0; i<m; i++)  printf("%d\n", ans[i]);
    }
    return 0;
}
View Code

树状数组、

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
const int MAXN=1e5+100;
int tree[MAXN];
int n;
int lowbit(int x)
 {
     return x&(-x);
 }
 
 void add(int pos,int val)
 {
     while(pos <=n)
     {
         tree[pos] += val;
         pos += lowbit(pos);
     }
 }
 
 int read(int x)
 {
     int s=0;
     while(x>0)
     {
         s += tree[x];
         x -= lowbit(x);//x-lowbit(x)可以理解成变成了x的兄弟
     }
     return s;
 }
int A[MAXN],pos[MAXN];
struct node{
    int l,r,index;
    bool operator <(const node& rsh)const{
        if(r==rsh.r)
            return l<rsh.l;
        else return r<rsh.r;
    }
};
vector<node> Q;
int ans[MAXN];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int m;
        scanf("%d%d",&n,&m);
        REP(i,1,n){
            scanf("%d",&A[i]);
            pos[A[i]]=i;
        }
        Q.clear();
        node tmp;
        REP(i,1,m)
        {
            scanf("%d%d",&tmp.l,&tmp.r);
            tmp.index=i;
            Q.push_back(tmp);
        }
        sort(Q.begin(),Q.end());
        CL(tree,0);
        int j=0;
        for(int i=1;i<=n;i++)
        {
            add(i,1);
            if(A[i]+1<=n&&pos[A[i]+1]<i)
            {
                add(pos[A[i]+1],-1);
            }
            if(A[i]-1>=1&&pos[A[i]-1]<i)
            {
                add(pos[A[i]-1],-1);
            }
            while(Q[j].r==i)
            {
                ans[Q[j].index]=read(Q[j].r)-read(Q[j].l-1);
                j++;
            }
        }
        REP(i,1,m)
        {
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}
View Code

 

posted @ 2015-08-17 13:45  mithrilhan  阅读(174)  评论(0编辑  收藏  举报