hdu 4638 Group (离线树状数组)
2015-08-01 21:22
316 查看
/* 题意: 在l到r之间有多少段连续的数 离线处理每个查询,遍历每个点,设当前处理的区间终点为R, 处理每个查询的时候,首先假设所有的数a[i]都是自己独立成段, 如果有a[i]+1,或者a[i]-1的数在区间[L,R]内,那么它肯定不是独立成段的, 也就是我们要减去在[L,R]内不独立成段的数的个数。 问题就转化为查询[L,R]之前不独立成段的数的个数。 可以这样处理,对于a[i],如果发现a[i]-1,或者a[i]+1的位置, 在[1,R]之间,那么我们在相应位置加上1,直接查询区间[L,R]内有多少1就可以了。 */ # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; struct node { int l,r,poss; }; node p[100010]; int c[100010]; int n; bool cmp(node a1,node a2) { if(a1.r==a2.r) return a1.l<a2.l; return a1.r<a2.r; } int lowbit(int x) { return x&(-x); } void update(int p,int val) { while(p<=n) { c[p]+=val; p+=lowbit(p); } } int sum(int x) { int res=0; while(x>0) { res+=c[x]; x-=lowbit(x); } return res; } int a[100010]; int pos[100010]; int num[100010]; int main() { int t,m,i,j; while(~scanf("%d",&t)) { while(t--) { scanf("%d%d",&n,&m); for(i=1; i<=n; i++) { scanf("%d",&a[i]); pos[a[i]]=i; } for(i=1; i<=m; i++) { scanf("%d%d",&p[i].l,&p[i].r); p[i].poss=i; } sort(p+1,p+1+m,cmp); memset(c,0,sizeof(c)); j=1; for(i=1; i<=n; i++) { update(i,1); if(pos[a[i]+1]<i&&a[i]<n) update(pos[a[i]+1],-1); if(pos[a[i]-1]<i&&a[i]>1) update(pos[a[i]-1],-1); while(j<=m&&p[j].r==i) { num[p[j].poss]=sum(p[j].r)-sum(p[j].l-1); j++; } } for(i=1; i<=m; i++) printf("%d\n",num[i]); } } return 0; }
相关文章推荐
- zoj 3822 概率dp
- 查看文件常用指令cat,tac,nl,more,less,head,tail,od
- Deep Learning for Nature Language Processing --- 第八讲
- OPENWRT网络打印机TCP/IP共享设置教程 以703N为例
- JAVA基础一大堆0801接口+匿名类+IO流
- 08-01 接口 异常 文件IO流
- Python简单的爬虫
- Web-服务器推送push——websocket、ajax轮询
- 部分32位Windows数据类型的介绍
- 亚信仨月印象(国庆时再写)
- 佛家经典禅语语录句子
- 佛家经典禅语语录句子
- 连续子数组求和
- MATLAB 基本数据类型和调用方式
- 做一个靠谱的iOS开发者(1)
- 在RedHat Server 5.4上安装YUM【利用网易免费yum源,配置和更新yum】
- 12.深浅拷贝
- Openfiler 配置iscsi iSCSI Targets 不能添加 Target IQN
- java培训 2015-07-31
- ISE中FPGA的实现流程