zoukankan      html  css  js  c++  java
  • Codeforces765F. Souvenirs

    $n leq 100000$的数列给$m leq 300000$的询问,每次问一个区间里选两个数差的最小值。数字$leq 1e9$。

    根号算法:

    无脑莫队加个平衡树或者权值线段树来查前驱后继是$n sqrt{n} log_2n$的。

    如果只有删除可以用链表实现,所以想办法去掉插入操作。对左端点$l$在一块$[x,y]$中的询问,可以先用链表处理出所有$i>y$的$a_i$在$[y+1,i-1]$的前驱后继,接下来只要查$[l,y]$间的数字在$[y+1,r]$中的前驱后继即可。这时把询问的$r$从大到小排序,回答每个询问的时候,左边直接删除至$y$回答询问,然后暴力把链表改回去即可。这样$m sqrt{n}$。

    数据结构:

    看看一个$i$会和哪些数搞起来对答案产生贡献。先找$j>i,a_j geq a_i$的,$a_j<a_i$的同理。若找$a_j geq a_i$,那么找到的数字将是个递减数列。如果数据随机,这递减数列是$log_2Max$级别长度的。但专门构造数据可以卡掉。

    假如我们已经找了个$j$,要找下一个和$i$搭配能产生贡献的数,假设是$a_k,k>j$,那么有$a_i leq a_k leq a_j$,就是上面说的递减数列。除此之外,$a_k-a_i<a_j-a_k$,这啥?因为如果不满足他,$a_j$和$a_k$将比$a_i$和$a_k$优,$i$和$k$又远又大就没用了!!这样有贡献的点对就是$nlog_2Max$级别了,加个二维数点就可以$log^2$通过。

    怎么找点对,可以用主席树,也可以把$a_i$排序加入线段树,在线段树上二分得到。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<time.h>
      5 //#include<complex>
      6 //#include<queue>
      7 #include<algorithm>
      8 #include<stdlib.h>
      9 using namespace std;
     10 
     11 #define LL long long
     12 int qread()
     13 {
     14     char c; int s=0; while ((c=getchar())<'0' || c>'9');
     15     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s;
     16 }
     17 
     18 //Pay attention to '-' and LL of qread!!!!
     19 
     20 int n,lq;
     21 #define maxn 200011
     22 #define maxm 1000011
     23 int a[maxn];
     24 struct Poi{int v,id; bool operator < (const Poi &b) const {return v>b.v;}}p[maxn];
     25 
     26 struct Ques{int x,y,v; bool operator < (const Ques &b) const {return x>b.x;}}q[maxm],aa[maxn*60];
     27 int la=0;
     28 
     29 struct SMT
     30 {
     31     struct Node
     32     {
     33         int ls,rs;
     34         int Max,Min;
     35     }a[maxn<<1];
     36     int size,n;
     37     void up(int x)
     38     {
     39         Node &b=a[x],&p=a[a[x].ls],&q=a[a[x].rs];
     40         b.Max=max(p.Max,q.Max); b.Min=min(p.Min,q.Min);
     41     }
     42     void build(int &x,int L,int R)
     43     {
     44         x=++size;
     45         if (L==R) {a[x].ls=a[x].rs=0; a[x].Max=-2e9; a[x].Min=2e9; return;}
     46         int mid=(L+R)>>1;
     47         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R); up(x);
     48     }
     49     void build() {int x; build(x,1,n);}
     50     void clear(int m) {n=m; size=0; build();}
     51     int ql,qr,v;
     52     void Modify(int x,int L,int R)
     53     {
     54         if (L==R) {a[x].Max=a[x].Min=v; return;}
     55         int mid=(L+R)>>1;
     56         if (ql<=mid) Modify(a[x].ls,L,mid); else Modify(a[x].rs,mid+1,R);
     57         up(x);
     58     }
     59     void modify(int pos,int v) {ql=pos; this->v=v; Modify(1,1,n);}
     60     int Query1(int x,int L,int R)
     61     {
     62         if (L==R) {return (L>=ql && a[x].Min<=v)?L:0;}
     63         int mid=(L+R)>>1;
     64         if (ql>mid) return Query1(a[x].rs,mid+1,R);
     65         if (ql<=L)
     66         {
     67             if (a[a[x].ls].Min<=v) return Query1(a[x].ls,L,mid);
     68             if (a[a[x].rs].Min<=v) return Query1(a[x].rs,mid+1,R);
     69             return 0;
     70         }
     71         int tmp=Query1(a[x].ls,L,mid);
     72         if (tmp) return tmp;
     73         if (a[a[x].rs].Min<=v) return Query1(a[x].rs,mid+1,R);
     74         return 0;
     75     }
     76     int query1(int pos,int v) {if (pos>n) return 0; ql=pos; this->v=v; return Query1(1,1,n);}
     77     int Query2(int x,int L,int R)
     78     {
     79         if (L==R) {return (L>=ql && a[x].Max>=v)?L:0;}
     80         int mid=(L+R)>>1;
     81         if (ql>mid) return Query2(a[x].rs,mid+1,R);
     82         if (ql<=L)
     83         {
     84             if (a[a[x].ls].Max>=v) return Query2(a[x].ls,L,mid);
     85             if (a[a[x].rs].Max>=v) return Query2(a[x].rs,mid+1,R);
     86             return 0;
     87         }
     88         int tmp=Query2(a[x].ls,L,mid);
     89         if (tmp) return tmp;
     90         if (a[a[x].rs].Max>=v) return Query2(a[x].rs,mid+1,R);
     91         return 0;
     92     }
     93     int query2(int pos,int v) {if (pos>n) return 0; ql=pos; this->v=v; return Query2(1,1,n);}
     94 }smt;
     95 
     96 struct BIT
     97 {
     98     int a[maxn],n;
     99     void clear(int m) {n=m; for (int i=1;i<=n;i++) a[i]=2e9;}
    100     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]=min(a[x],v);}
    101     int query(int x) {int ans=2e9; for (;x;x-=x&-x) ans=min(ans,a[x]); return ans;}
    102 }bit;
    103 
    104 int ans[maxm];
    105 int main()
    106 {
    107     n=qread();
    108     for (int i=1;i<=n;i++) a[i]=qread();
    109     lq=qread();
    110     for (int i=1;i<=lq;i++) q[i].x=qread(),q[i].y=qread(),q[i].v=i;
    111     
    112     for (int i=1;i<=n;i++) p[p[i].id=i].v=a[i];
    113     sort(p+1,p+1+n);
    114     smt.clear(n);
    115     for (int i=1;i<=n;i++)
    116     {
    117         int id=p[i].id,v=p[i].v;
    118         smt.modify(id,v);
    119         int wow=2e9+1,tmp,now=id+1;
    120         while (wow!=v && (tmp=smt.query1(now,(wow+0ll+v)>>1))) wow=a[tmp],aa[++la]=(Ques){id,tmp,wow-v},now=tmp+1;
    121     }
    122     
    123     smt.clear(n);
    124     for (int i=n;i;i--)
    125     {
    126         int id=p[i].id,v=p[i].v;
    127         smt.modify(id,v);
    128         int wow=-1e9,tmp,now=id+1;
    129         while (wow!=v && (tmp=smt.query2(now,(wow+1ll+v)>>1))) wow=a[tmp],aa[++la]=(Ques){id,tmp,v-wow},now=tmp+1;
    130     }
    131     
    132     sort(aa+1,aa+1+la); sort(q+1,q+1+lq);
    133     bit.clear(n);
    134     for (int i=1,j=1;i<=lq;i++)
    135     {
    136         while (j<=la && aa[j].x>=q[i].x) bit.add(aa[j].y,aa[j].v),j++;
    137         ans[q[i].v]=bit.query(q[i].y);
    138     }
    139     for (int i=1;i<=lq;i++) printf("%d
    ",ans[i]);
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    【二】调通单机版的thrift-C++版本
    【一】调通单机版的thrift-python版本
    Spark在实际项目中分配更多资源
    Spark实际项目中调节并行度
    IDEA中大小写转换快捷键
    使用maven下载cdh版本的大数据jar包
    【Hive六】Hive调优小结
    【Hive五】Hive函数UDF
    【Hbase三】Java,python操作Hbase
    【Hive三】Hive理论
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8871677.html
Copyright © 2011-2022 走看看