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
- HDU 4638 分块Or树状数组
- hdu 5193 分块 树状数组 逆序对
- bzoj2141【分块+树状数组】
- HDU 4638 Group 【树状数组,分块乱搞(莫队算法?)】
- HDU 5057 Argestes and Sequence (离线树状数组 || 分块)
- hdu 4638 树状数组
- 2141: 排队 分块+树状数组
- SDOI 2009 (COGS 421)HH的项链 分块or树状数组
- 【树状数组or归并排序求逆序数】HDU 1394
- HDU 3333 Turing Tree 线段树 or 树状数组
- hdu 1166敌兵布阵(树状数组or线段树)
- hdu 1166 敌兵布阵(线段树OR树状数组)
- HDU 4217 Data Structure? 线段树 OR 树状数组
- hdu 3854 Glorious Array(线段树or树状数组)
- hdu 1166 敌兵布阵(树状数组 or 线段树)
- poj 2352 OR hdu 1541 Stars(数据结构:树状数组)
- HDU - 1166 - 敌兵布阵 (树状数组 or 线段树)
- hdu 1166 敌兵布阵【线段树Or树状数组】
- 第十八题(约瑟夫环问题)
- 防止浏览器缓存css,js静态文件
- 栈之进制转换
- 第4条:通过私有构造器强化不可实例化的能力
- 数据库完整性约束
- HDU 4638 分块Or树状数组
- smarty备忘录
- Ubuntu下面安装JAVA
- 推荐30款最佳的数据可视化工具
- DHT网络原理制作bt采集蜘蛛,开源版
- Myeclipse重装后的必要配置
- RedHat下挂载U盘
- Bloom Filter概念和原理
- android加速度传感器简单实现