zoukankan      html  css  js  c++  java
  • 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    先删去所有只能进入一个洞的机器人,这对答案没有贡献

    考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀(min max),我们直接按照前缀(min max)(DP)

    把前缀(min max)设成坐标,转成格路问题,现在就变成了平面上有若干点要用一条折线分开这些点使得(n)对配对点在平面的两侧。

    由于我们要保证方案不重,所以要钦定经过某个配对关系的下面那个点,转移方程是

    [f_i=sum_{x_j<x_i,y_j<y_i}f_j ]

    直接树状数组维护(DP)即可

    由于我有点赶时间,说的不是很详细(反正没人看),所以挂个连接如果不懂去那里看。【ARC101F】Robots and Exits 树状数组优化DP

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define lowbit(x) ((x)&(-(x)))
    
    using namespace std;  typedef long long ll;
    inline int qr(){
          register int ret=0,f=0;
          register char c=getchar();
          while(c<48||c>57)f|=c==45,c=getchar();
          while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
          return f?-ret:ret;
    }
    
    
    const int mod=1e9+7;
    const int maxn=5e5+5;
    pair < int , int > fal[maxn];
    int seg[maxn<<1|1];
    int pos[maxn];
    vector < int > ve;
    int tmp[maxn];
    int n,m,ans=1;
    int len;
    
    inline void add(const int&pos,const int&tag){
          for(register int t=pos;t<=len;t+=lowbit(t)) seg[t]=(seg[t]+tag)%mod;
    }
    
    inline int que(const int&pos){
          register int ret=0;
          for(register int t=pos;t;t-=lowbit(t)) ret=(ret+seg[t])%mod;
          return ret;
    }
    
    
    inline int divd(const int&data){
          register int l=1,r=m,mid,ret=-1;
          do{
    	    mid=(l+r)>>1;
    	    if(pos[mid]<data) l=mid+1,ret=mid;
    	    else r=mid-1;
          }while(l<=r);
          return ret;
    }
    
    int main(){
          freopen("robot.in","r",stdin);
          freopen("robot.out","w",stdout);
          n=qr();m=qr();
          for(register int t=1;t<=n;++t) tmp[t]=qr();
          for(register int t=1;t<=m;++t) pos[t]=qr();
                
          for(register int t=1;t<=n;++t){
    	    if(tmp[t]<pos[1]||tmp[t]>pos[m])continue;
    	    register int k=lower_bound(pos+1,pos+m+1,tmp[t])-pos;
    	    fal[t].second=pos[k]-tmp[t];
    	    k=divd(tmp[t]);
    	    fal[t].first=tmp[t]-pos[k];
    	    ve.push_back(fal[t].second);
          }
          sort(ve.begin(),ve.end());
          ve.resize(unique(ve.begin(),ve.end())-ve.begin());
          for(auto t:ve) tmp[++tmp[0]]=t;
          for(register int t=1;t<=n;++t){
    	    if(!fal[t].first||!fal[t].second)continue;
    	    fal[t].second=-(lower_bound(tmp+1,tmp+tmp[0]+1,fal[t].second)-tmp);
          }
          len=m;
          sort(fal+1,fal+n+1);
          int ed=unique(fal+1,fal+n+1)-fal-1;
          for(register int t=1;t<=ed;++t){
    	    if(((!fal[t].second)||(!fal[t].first))) continue;
    	    register int s=que(-fal[t].second-1)+1;
    	    ans=(ans+s)%mod;
    	    add(-fal[t].second,s);
          }
          printf("%d
    ",ans);
          return 0;
    }
    
    
  • 相关阅读:
    pinus学习(3)
    pinus学习(2)
    HBASE架构解析(二)
    排序算法
    泛型原理
    《JAVA NIO》第二章缓冲区
    @SuppressWarnings
    网络编程
    synchronized原理
    第十六节:pandas之日期时间
  • 原文地址:https://www.cnblogs.com/winlere/p/11300892.html
Copyright © 2011-2022 走看看