HDU 4638 分块Or树状数组

来源:互联网 发布:button按钮跳转js函数 编辑:程序博客网 时间:2024/06/08 14:41

给你一个1~N的排列,问区间[L, R] 之间有多少段连续的数。比如区间里有3、1、2、5、6,这五个数,那么就有3、1、2和5、6这两段。

询问一个区间的时候,可以一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已经添加在内,如果两个都在,则总段数减1,如果两个都不在,总段数加1,其他情况总段数不变了。



const int maxn = 100100 ;struct  Q{        int l , r , id , p ;        friend bool operator < (const Q A , const Q B){             if(A.p == B.p) return A.r < B.r ;             else  return A.p < B.p ;        }}q[maxn + 8] ;int  a[maxn + 8] ;int  ans[maxn + 8] ;int  L , R , sum ;bool vis[maxn + 8] ;void add(int x){     vis[x] = 1 ;     if(vis[x-1] && vis[x+1]) sum-- ;     else if(!vis[x-1] && !vis[x+1]) sum++ ;}void del(int x){     vis[x] = 0 ;     if(vis[x-1] && vis[x+1]) sum++ ;     else if(!vis[x-1] && !vis[x+1]) sum-- ;}int  ask(int l , int r , int id){     int i ;     if(id == 0){         sum = 0 ;         for(i = l ; i <= r ; i++)  add(a[i]) ;         L = l , R = r ;         return sum ;     }     for(i = l ; i < L ; i++) add(a[i]) ;     for(i = R+1 ; i <= r ; i++) add(a[i]) ;     for(i = L ; i < l ; i++) del(a[i]) ;     for(i = r+1 ; i <= R ; i++) del(a[i]) ;     L = l , R = r ;     return sum ;}int  main(){     int i , j , n  , m  , t ;     int blocksize ;     cin>>t ;     while(t--){          scanf("%d%d" , &n , &m) ;          for(i = 1 ; i <= n ; i++) scanf("%d" ,&a[i]) ;          blocksize = sqrt(0.5 + n) ;          for(i = 0 ; i < m ; i++){               scanf("%d%d" , &q[i].l , &q[i].r) ;               q[i].id = i ;               q[i].p = q[i].l / blocksize ;          }          memset(vis , 0 , sizeof(vis)) ;          sort(q , q+m) ;          for(i = 0 ; i < m ; i++)              ans[q[i].id] = ask(q[i].l , q[i].r , i) ;          for(i = 0 ; i < m ; i++) printf("%d\n" , ans[i]) ;     }     return 0 ;}



#include <iostream>#include <string>#include <string.h>#include <vector>#include <stdio.h>#include <algorithm>#include <map>#include <math.h>typedef long long LL ;const int N = 100008 ;int  n ;namespace BIT{    int val[N] ;    int lowbit(int x){        return x & (-x) ;    }    void add(int idx , int c){         for(; idx <=n ; idx += lowbit(idx)) val[idx] += c ;    }    int sum(int idx){        int res = 0 ;        for(; idx ; idx -= lowbit(idx)) res += val[idx] ;        return res ;    }    int sum(int l , int r){        return sum(r) - sum(l-1) ;    }    void clear(){         std::fill(val , val + 1 + n , 0) ;    }}int  position[N] , a[N]  , vis[N] , res[N] ;struct Query{    int Lf , Rt , idx ;    friend bool operator < (const Query &a , const Query &b){         return a.Rt < b.Rt ;    }};Query q[N] ;int main(){    std::ios::sync_with_stdio(false) ;    int t , m ;    scanf("%d" , &t) ;    while(t--){        scanf("%d%d" , &n , &m) ;        for(int i = 1 ; i <= n ; i++){            scanf("%d" , &a[i]) ;            position[a[i]] = i ;        }        for(int i = 0 ; i < m ; i++){            scanf("%d%d" , &q[i].Lf , &q[i].Rt ) ;            q[i].idx = i ;        }        std::sort(q , q + m) ;        BIT::clear() ;        std::fill(vis , vis + 1 + n , 0) ;        int idx = 0 ;        for(int i = 1 ; i <= n ; i++){            vis[a[i]] = 1 ;            BIT::add(i , 1) ;            if(vis[a[i]-1]) BIT::add(position[a[i]-1] , -1) ;            if(vis[a[i]+1]) BIT::add(position[a[i]+1] , -1) ;            while(idx < m && q[idx].Rt == i){                 res[q[idx].idx] = BIT::sum(q[idx].Lf, q[idx].Rt) ;                 idx++ ;            }        }        for(int i = 0 ; i < m ; i++) printf("%d\n" , res[i]) ;    }    return 0 ;}



0 0
原创粉丝点击