zoukankan      html  css  js  c++  java
  • CF765F Souvenirs

    Link
    先看暴力做法。
    把询问按右端点升序排序。
    对于每个(r),我们处理出左端点(lin[1,r))的所有答案(ans_l),当(r)向右扩展时暴力修改(ans)
    这样子显然不能过,我们考虑优化。
    我们可以认为(ans_l=minlimits_{i=l}^{r-1}ans_i),因此显然(ans)是单调不减的。
    如果我们把单点查询改成区间查询最小值,那么我们就可以在修改时不修改每个(ans),只需要修改一部分(ans)
    我们选择线段树维护。
    具体而言,当把(r)扩展到(r+1)时,我们在线段树上从右往左修改(ans),如果我们修改了某个(ans),且当前的答案为(mn),那么在之后的修改时,如果某个节点(也就是这个节点左边的节点)的贡献小于(mn),那么就没有必要继续递归进入其子节点了。
    如何更新某个线段树节点的答案呢?在每个线段树的节点开个vector记录这个节点代表的区间内的所有数,更新时二分一下即可。

    #include<bits/stdc++.h>
    #define IT vector<int>::iterator
    #define pb push_back
    #define ls p<<1
    #define rs p<<1|1
    #define mid ((l+r)>>1)
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[20],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
        void Put(char x){*oS++=x;if(oS==oT)Flush();}
        int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
        void write(int x){int top=0;if(!x)Put('0');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('
    ');}
    }
    using namespace IO;
    int min(int a,int b){return a<b? a:b;}
    const int N=200007,M=300007,INF=1e9;
    int a[N],ans[N<<2],Ans[N],n,m,mn;
    vector<int>vec[N<<2];
    struct node{int l,r,id;}q[M];
    int operator<(node a,node b){return a.r<b.r;}
    void build(int p,int l,int r)
    {
        for(int i=l;i<=r;++i) vec[p].pb(a[i]);
        sort(vec[p].begin(),vec[p].end()),ans[p]=INF;
        if(l==r) return;
        build(ls,l,mid),build(rs,mid+1,r);
    }
    int query(int p,int l,int r,int L,int R)
    {
        if(L==l&&r==R) return ans[p];
        return R<=mid? query(ls,l,mid,L,R):(L>mid? query(rs,mid+1,r,L,R):min(query(ls,l,mid,L,mid),query(rs,mid+1,r,mid+1,R)));
    }
    void update(int p,int l,int r,int f,int x)
    {
         if(r<=f)
         {
    	 IT it=upper_bound(vec[p].begin(),vec[p].end(),x);
    	 if(it!=vec[p].end()) ans[p]=min(ans[p],*it-x);
    	 if(it!=vec[p].begin()) ans[p]=min(ans[p],x-*(it-1));
    	 if(mn<=ans[p]) return;
    	 if(l==r) return (void)(mn=min(mn,ans[p]));
         }
         if(f>mid) update(rs,mid+1,r,f,x);
         update(ls,l,mid,f,x),ans[p]=min(ans[p],min(ans[ls],ans[rs])),mn=min(mn,ans[p]);
    }
    int main()
    {
        int i,j;n=read();
        for(i=1;i<=n;++i) a[i]=read();
        build(1,1,n),m=read();
        for(i=1;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
        sort(q+1,q+m+1);
        for(j=1,i=2;i<=n;++i)
        {
            mn=INF,update(1,1,n,i-1,a[i]);
            for(;j<=m&&q[j].r<=i;++j) Ans[q[j].id]=query(1,1,n,q[j].l,i);
        }
        for(i=1;i<=m;++i) write(Ans[i]);
        return Flush(),0;
    }
    
  • 相关阅读:
    利用朴素贝叶斯算法进行分类-Java代码实现
    机器学习项目中常见的误区
    Chromium项目文化
    又一次定义CDN:为什么是迅雷?
    程序猿的思维修炼
    linux杂谈(十二):CDN加速
    Run-Time Check Failure #2
    打开excel2007&quot;向程序发送命令时出现故障&quot;
    [Unity 3D] Quaternion.LookRotation
    具体解释 IBM Bluemix 端到端开发体验
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11545583.html
Copyright © 2011-2022 走看看