zoukankan      html  css  js  c++  java
  • [hdoj6483][莫队+线段树/ST]

    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),但常数很大,都不适合放在莫队里面
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define debug(x) cout<<"["<<#x<<"]"<<"  "<<x<<endl;
      5 const int maxn=1e5+5;
      6 int a[maxn],b[maxn],c[maxn],in[maxn];
      7 struct node{
      8     int maxx;
      9     int minn;
     10     int l;
     11     int r;
     12 }Node[maxn<<2];
     13 struct Qa{
     14     int l;
     15     int r;
     16     int id;
     17     int bloc;
     18 }q[maxn];
     19 int ANS[maxn];
     20 void pushup(int rt){
     21     Node[rt].maxx=max(Node[rt<<1].maxx,Node[(rt<<1)|1].maxx);
     22     Node[rt].minn=min(Node[rt<<1].minn,Node[(rt<<1)|1].minn);
     23 }
     24 void build(int L,int R,int rt){
     25     Node[rt].l=L;
     26     Node[rt].r=R;
     27     if(L==R){
     28         Node[rt].maxx=Node[rt].minn=a[L];
     29         return;
     30     }
     31     int mid=(L+R)/2;
     32     build(L,mid,rt<<1);
     33     build(mid+1,R,(rt<<1)|1);
     34     pushup(rt);
     35 }
     36 bool cmp(struct Qa aa,struct Qa bb){
     37     if(aa.bloc==bb.bloc)return aa.r<bb.r;
     38     return aa.bloc<bb.bloc;
     39 }
     40 void query(int L,int R,int rt,int L1,int R1,int &m1,int &m2){
     41     //debug(L);
     42     if(L1<=L&&R1>=R){
     43         m1=max(m1,Node[rt].maxx);
     44         m2=min(m2,Node[rt].minn);
     45         return;
     46     }
     47     int mid=(L+R)/2;
     48     if(mid>=L1)query(L,mid,rt<<1,L1,R1,m1,m2);
     49     if(mid<R1)query(mid+1,R,(rt<<1)|1,L1,R1,m1,m2);
     50 }
     51 int main()
     52 {
     53     //cout<<100000ll*sqrt(100000)+400000ll*log(100000)<<endl;
     54     int t;
     55     scanf("%d",&t);
     56     while(t--){
     57         int n,m;
     58         scanf("%d%d",&n,&m);
     59         //unordered_map<int,int>mp;
     60         for(int i=1;i<=n;i++){
     61             scanf("%d",&a[i]);
     62             b[i]=a[i];
     63             in[i]=0;
     64         }
     65         build(1,n,1);
     66         int len=sqrt(n);
     67         for(int i=1;i<=m;i++){
     68             scanf("%d%d",&q[i].l,&q[i].r);
     69             q[i].id=i;
     70             q[i].bloc=q[i].l/len;
     71             ANS[i]=0;
     72         }
     73         sort(q+1,q+1+m,cmp);
     74         sort(b+1,b+1+n);
     75         int L=1;
     76         int R=1;
     77         int tot=1;
     78         int kk=unique(b+1,b+1+n)-b-1;
     79         for(int i=1;i<=n;i++){
     80             int pos=lower_bound(b+1,b+1+kk,a[i])-b;
     81             c[i]=pos;
     82         }
     83         in[c[1]]++;
     84         for(int i=1;i<=m;i++){
     85             int m1=a[q[i].l];
     86             int m2=a[q[i].r];
     87             query(1,n,1,q[i].l,q[i].r,m1,m2);
     88             while(L<q[i].l){
     89                 in[c[L]]--;
     90                 if(in[c[L]]==0){
     91                     tot--;
     92                 }
     93                 L++;
     94             }
     95             while(L>q[i].l){
     96                 L--;
     97                 in[c[L]]++;
     98                 if(in[c[L]]==1){
     99                     tot++;
    100                 }
    101             }
    102             while(R>q[i].r){
    103                 in[c[R]]--;
    104                 if(in[c[R]]==0){
    105                     tot--;
    106                 }
    107                 R--;
    108             }
    109             while(R<q[i].r){
    110                 R++;
    111                 in[c[R]]++;
    112                 if(in[c[R]]==1){
    113                     tot++;
    114                 }
    115             }
    116             if(tot==m1-m2+1){
    117                 ANS[q[i].id]=1;
    118             }
    119         }
    120         for(int i=1;i<=m;i++){
    121             if(ANS[i]){
    122                 printf("YES
    ");
    123             }
    124             else{
    125                 printf("NO
    ");
    126             }
    127         }
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    Android Watchdog
    Android Zygote进程是如何fork一个APP进程的
    java多线程面试题小结
    Java Socket通信以及可能出现的问题解决
    Java对象的浅拷贝和深拷贝&&String类型的赋值
    AtomicLong和LongAdder的区别
    JDK中Concurrent包介绍及使用(包含atomic包/lock包/并发容器/执行器)
    final关键字总结
    Java内存模型-final域的内存语义--没明白,预留以后继续理解
    synchronized底层实现原理&CAS操作&偏向锁、轻量级锁,重量级锁、自旋锁、自适应自旋锁、锁消除、锁粗化
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/10862477.html
Copyright © 2011-2022 走看看