HDU 4638-Group(线段树+离线处理)
2015-08-16 21:06
351 查看
题意:
给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的)
分析:
我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号,要考虑和他相邻的标号的位置,若前面位置出现了和它相邻的标号,
则前面位置组数减一(因为可以合并成一组),查询区间离线处理,保证了查询的正确。
给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的)
分析:
我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号,要考虑和他相邻的标号的位置,若前面位置出现了和它相邻的标号,
则前面位置组数减一(因为可以合并成一组),查询区间离线处理,保证了查询的正确。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<1|1 #define All 1,N,1 #define N 100010 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; //pos 相邻标号在前面出现的位置 int sum[N*4],n,pos ,e,a ,tmp ; struct que{ int l,r,id; }q ; bool cmp(que x,que y){ return x.r<y.r; } void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void build(int l,int r,int rt){ if(l==r){ sum[rt]=1; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } void update(int p,int v,int l,int r,int rt){ if(l==r){ sum[rt]+=v; return; } int m=(l+r)>>1; if(p<=m)update(p,v,lson); else update(p,v,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r){ return sum[rt]; } int m=(l+r)>>1; int num=0; if(L<=m)num+=query(L,R,lson); if(R>m)num+=query(L,R,rson); return num; } void solve(){ sort(q+1,q+e+1,cmp); memset(pos,0,sizeof(pos)); build(1,n,1); int b=1; for(int i=1;i<=n;++i){ if(pos[a[i]-1]) update(pos[a[i]-1],-1,1,n,1); if(pos[a[i]+1]) update(pos[a[i]+1],-1,1,n,1); pos[a[i]]=i; while(b<=e&&q[b].r==i){ tmp[q[b].id]=query(q[b].l,q[b].r,1,n,1); b++; } } for(int i=1;i<=e;++i) printf("%d\n",tmp[i]); } int main() { int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&e); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=e;++i){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } solve(); } return 0; }
相关文章推荐
- Linux上有两种时间,一种是硬件时间,一种是系统时间
- 2012各大公司的C++试题
- 机房收费系统之临时收费金额
- 四种人吃花生加重病情
- struct stat 的用法
- Java 对象
- hdu 1874 畅通工程续 dijsktra dijkstra+邻接表 优先队列 bellman-ford bellman-ford队列优化(基础题目,一步步优化)
- hdu 5137 How Many Maos Does the Guanxi Worth(dijkstra && floyd)
- lr_eval_string函数在订飞机票中的例子-返回脚本中参数的值
- android中一个解决办法
- Java多重循环算法问题:(九九乘法表、打印平行四边形、打印空心菱形、打印菱形、搬砖问题、斐波那契数列、猴子吃桃问题、回文数、1!+2!+...+20!)
- 再看“陈伟视频”理解多态机制 ——你还记得“橘子,苹果的例子么”
- 07 映射和集合类型 - 《Python 核心编程》
- 自定义spring schema简化与canal集成
- Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试
- JavaEE SSH集成框架(两) struts2 本地加载dtd文件,action组态
- ES6 新特性
- python2.7版本 xlutils库下载
- java中IO流学习小结
- 小白书之二叉树指针法构建二叉树以及二叉树先序遍历