A Sequence Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 712    Accepted Submission(s): 114

Problem Description
One day, WNJXYK found a very hard problem on an Online Judge. This problem is so hard that he had been thinking about the solutions for a couple of days. And then he had a surprise that he misunderstood that problem and easily figured out a solution using segment tree. Now he still wonders that solution for the misread problem.
There is a sequence with N positive integers A1,A2,...,An and M queries. Each query will give you an interval [L,R] and require an answer with YES/NO indicates that whether the numbers in this interval are continuous in its integer range. 
Let us assume that the maximal number in an interval is mx and the minimal number is mi. The numbers in this interval are continuous in its integer range means that each number from mi to mx appears at least once in this interval.
 
Input
The input starts with one line contains exactly one positive integer T which is the number of test cases. And then there are T cases follow.
The first line contains two positive integers n,m which has been explained above.The second line contains positive integers A1,A2,...,An.
Then there will be m lines followed. Each line contains to positive numbers Li,Ri indicating that the ith query’s interval is [Li,Ri].
 
Output
For each test case, output m line.
Each of following m lines contains a single string “YES”/ “NO” which is the answer you have got.
 
Sample Input
2
3 3
3 1 2
2 3
1 3
1 2
5 3
1 2 2 4 5
1 5
1 3
3 3
 
Sample Output
YES
YES
NO
NO
YES
YES

Hint

T=5
1<=n<=100000
1<=Ai<=10^9
1<=m<=100000
The input file is very large, so you are recommend to use scanf() and printf() for IO.

题解:线段树/ST 求区间最大值和最小值,用莫队解决q次查询 复杂度4 *n*logn+nsqrt(q)。要注意莫队本身复杂度nsqrt(q)就很高了,所以尽量通过预处理使里面的基本操作复杂度变低,而且尽量采用离散化的方式来避免使用map和unordered_map,前者复杂度O(logn),后者虽然是O(1),但常数很大,都不适合放在莫队里面
 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<"["<<#x<<"]"<<" "<<x<<endl;
const int maxn=1e5+;
int a[maxn],b[maxn],c[maxn],in[maxn];
struct node{
int maxx;
int minn;
int l;
int r;
}Node[maxn<<];
struct Qa{
int l;
int r;
int id;
int bloc;
}q[maxn];
int ANS[maxn];
void pushup(int rt){
Node[rt].maxx=max(Node[rt<<].maxx,Node[(rt<<)|].maxx);
Node[rt].minn=min(Node[rt<<].minn,Node[(rt<<)|].minn);
}
void build(int L,int R,int rt){
Node[rt].l=L;
Node[rt].r=R;
if(L==R){
Node[rt].maxx=Node[rt].minn=a[L];
return;
}
int mid=(L+R)/;
build(L,mid,rt<<);
build(mid+,R,(rt<<)|);
pushup(rt);
}
bool cmp(struct Qa aa,struct Qa bb){
if(aa.bloc==bb.bloc)return aa.r<bb.r;
return aa.bloc<bb.bloc;
}
void query(int L,int R,int rt,int L1,int R1,int &m1,int &m2){
//debug(L);
if(L1<=L&&R1>=R){
m1=max(m1,Node[rt].maxx);
m2=min(m2,Node[rt].minn);
return;
}
int mid=(L+R)/;
if(mid>=L1)query(L,mid,rt<<,L1,R1,m1,m2);
if(mid<R1)query(mid+,R,(rt<<)|,L1,R1,m1,m2);
}
int main()
{
//cout<<100000ll*sqrt(100000)+400000ll*log(100000)<<endl;
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
//unordered_map<int,int>mp;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
in[i]=;
}
build(,n,);
int len=sqrt(n);
for(int i=;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
q[i].bloc=q[i].l/len;
ANS[i]=;
}
sort(q+,q++m,cmp);
sort(b+,b++n);
int L=;
int R=;
int tot=;
int kk=unique(b+,b++n)-b-;
for(int i=;i<=n;i++){
int pos=lower_bound(b+,b++kk,a[i])-b;
c[i]=pos;
}
in[c[]]++;
for(int i=;i<=m;i++){
int m1=a[q[i].l];
int m2=a[q[i].r];
query(,n,,q[i].l,q[i].r,m1,m2);
while(L<q[i].l){
in[c[L]]--;
if(in[c[L]]==){
tot--;
}
L++;
}
while(L>q[i].l){
L--;
in[c[L]]++;
if(in[c[L]]==){
tot++;
}
}
while(R>q[i].r){
in[c[R]]--;
if(in[c[R]]==){
tot--;
}
R--;
}
while(R<q[i].r){
R++;
in[c[R]]++;
if(in[c[R]]==){
tot++;
}
}
if(tot==m1-m2+){
ANS[q[i].id]=;
}
}
for(int i=;i<=m;i++){
if(ANS[i]){
printf("YES\n");
}
else{
printf("NO\n");
}
}
}
return ;
}

[hdoj6483][莫队+线段树/ST]的更多相关文章

  1. Codeforces 666E E - Forensic Examination SA + 莫队 + 线段树

    E - Forensic Examination 我也不知道为什么这个复杂度能过, 而且跑得还挺快, 数据比较水? 在sa上二分出上下界, 然后莫队 + 线段树维护区间众数. #include< ...

  2. 洛谷P3246 序列 [HNOI2016] 莫队/线段树+扫描线

    正解:莫队/线段树+扫描线 解题报告: 传送门! 似乎是有两种方法的,,,所以分别港下好了QAQ 第一种,莫队 看到这种询问很多区间之类的就会自然而然地想到莫队趴?然后仔细思考一下,发现复杂度似乎是欧 ...

  3. 【CF633H】Fibonacci-ish II 莫队+线段树

    [CF633H]Fibonacci-ish II 题意:给你一个长度为n的序列$a_i$.m个询问,每个询问形如l,r:将[l,r]中的所有$a_i$排序并去重,设得到的新数列为$b_i$,求$b_1 ...

  4. Manthan, Codefest 16 H. Fibonacci-ish II 大力出奇迹 莫队 线段树 矩阵

    H. Fibonacci-ish II 题目连接: http://codeforces.com/contest/633/problem/H Description Yash is finally ti ...

  5. [bzoj4358]permu:莫队+线段树/回滚莫队

    这道题是几天前水过去的,现在快没印象了,水一发. 首先我们看到它让求解的是最长的值域 连续段长度,很好. 然后就想到了山海经,但但是我还没有做. 然后又想到了很久以前的一次考试的T3旅馆hotel(我 ...

  6. BZOJ 4129 树上带修莫队+线段树

    思路: 可以先做做BZOJ3585 是序列上的mex 考虑莫队的转移 如果当前数字出现过 线段树上把它置成1 对于询问 二分ans 线段树上查 0到ans的和 是不是ans+1 本题就是把它搞到了序列 ...

  7. bzoj 3289: Mato的文件管理 莫队+线段树

    题目链接 给一些询问,每个询问给出区间[L, R] , 求这段区间的逆序数. 先分块排序, 然后对于每次更改, 如果是更改L, 那么应该查询区间内比他小的数的个数, 如果更改R, 查区间内比他大的数的 ...

  8. BZOJ 4358 坑 莫队+线段树 死T

    这是一个坑 竟然卡nsqrt(n)logn T死 等更 //By SiriusRen #include <cmath> #include <cstdio> #include & ...

  9. CF633H Fibonacci-ish II(莫队+线段树)

    温馨提示:本题十分卡常数,我手动开O2才过的.而数据范围不伦不类的n<=30000,常数小的O(n2)居然比O(n√nlogn)跑得快…… 考虑插进去一个元素对答案产生的影响.原本数列为Σa[i ...

随机推荐

  1. Prometheus入门到放弃(2)之Node_export安装部署

    1.下载安装 node_exporter服务需要在三台机器都安装,这里我们以一台机器为例: 地址:https://prometheus.io/download/ ### 另外两个节点部署时,需要先创建 ...

  2. git的快速入门

    Git是目前世界上最先进的分布式版本控制系统(注意,仅仅是一个程序,而不是正真意义上的系统). Why为什么需要版本控制? 场景1:大学毕业前夕,你在完成毕业论文,初稿A写好了,找老师修改,老师提出意 ...

  3. NOIP2017[提高组] 宝藏 题解

    解析 我们观察范围可以发现n非常的小,(一般来说不是搜索就是状压dp)所以说对于这题我们可以用记忆化搜索或者dp,我们发现起点不同那么最终答案也就不同,也就是说答案是跟起点有关的,于是我们便可以想到去 ...

  4. PAT(B) 1071 小赌怡情(Java)

    题目链接:1071 小赌怡情 (15 point(s)) 题目描述 常言道"小赌怡情".这是一个很简单的小游戏:首先由计算机给出第一个整数:然后玩家下注赌第二个整数将会比第一个数大 ...

  5. go 数据渲染到html页面 02

    渲染到浏览器页面 //把数据渲染到浏览器 package main import ( "fmt" "text/template" "net/http& ...

  6. PowerBuilder学习笔记之删除和加载PBL文件的方法

    删除PBL目录的方法:直接点删除键删除 加载PBL文件的方法:点Browse按钮选择PBL文件

  7. Mysql union和union all用法

    1: 什么时候用union和union all ?    我们经常会碰到这样的应用,两个表的数据按照一定的查询条件查询出来以后,需要将结果合并到一起显示出来,这个时候 就需要用到union和union ...

  8. Linux踢出登陆用户的正确姿势

    首先who(或w)查看需要杀死的终端名,然后执行: pkill -9 -t pts/? pkill相当于ps和kill的结合,用法和killall类似,根据进程名来杀死一类进程(kill是杀死单个) ...

  9. 怎样判断当前浏览器是PC浏览器还是手机浏览器

    可以通过检测navigator.userAgent字段中是否有"mobi"字段来检测是PC浏览器还是手机浏览器: /mobi/i.test(window.navigator.use ...

  10. 杭电2577 多数组dp问题

    Problem Description Pirates have finished developing the typing software. He called Cathy to test hi ...