zoukankan      html  css  js  c++  java
  • AT4353-[ARC101D]Robots and Exits【LIS】

    正题

    题目链接:https://www.luogu.com.cn/problem/AT4353


    题目大意

    数轴上有(n)个球(m)个洞,每次可以将所有球左移或者右移,球到洞的位置会掉下去。

    求有多少让球掉进不同洞的方案。

    (1leq n,mleq 10^5)


    解题思路

    设一个球距离左右洞的距离分别为((x,y)),那么一个球((x_1,y_1))对球((x_2,y_2))产生限制当且仅当(x_1leq x_2)(y_1geq y_2)

    那么我们相当于找一些两两没有限制的数字的集合,一种方法是按照(x)升序排序,然后求(y)的上升序列数量即可。

    时间复杂度(O(nlog n))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define lowbit(x) (x&-x)
    #define mp(x,y) make_pair(x,y)
    using namespace std;
    const ll N=1e5+10,P=1e9+7;
    ll n,m,cnt,bnt,b[N],x[N],y[N],t[N],ans;
    pair<ll ,ll >a[N];
    void Change(ll x,ll val){
    	while(x<=n){
    		(t[x]+=val)%=P;
    		x+=lowbit(x);
    	}
    	return;
    }
    ll Ask(ll x){
    	ll ans=0;
    	while(x){
    		(ans+=t[x])%=P;
    		x-=lowbit(x);
    	}
    	return ans;
    }
    signed main()
    {
    	freopen("hole.in","r",stdin);
    	freopen("hole.out","w",stdout);
    	scanf("%lld%lld",&n,&m);
    	for(ll i=1;i<=n;i++)scanf("%lld",&x[i]);
    	for(ll i=1;i<=m;i++)scanf("%lld",&y[i]);
    	ll z=1;
    	for(ll i=1;i<=n;i++){
    		while(z<=m&&y[z]<x[i])z++;
    		if(z==1||z>m||y[z]==x[i])continue;
    		a[++cnt]=mp(x[i]-y[z-1],x[i]-y[z]);
    		b[++bnt]=y[z]-x[i];
    	}
    	sort(a+1,a+1+cnt);
    	b[++bnt]=0;sort(b+1,b+1+bnt);
    	cnt=unique(a+1,a+1+cnt)-a-1;
    	bnt=unique(b+1,b+1+bnt)-b-1;
    	Change(1,1);ans=1;
    	for(ll i=1;i<=cnt;i++){
    		ll w=lower_bound(b+1,b+1+bnt,-a[i].second)-b;;
    		ll sum=Ask(w-1);Change(w,sum);
    		(ans+=sum)%=P;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Java基础08 继承
    Java基础07 包
    Java基础06 组合
    Java基础05 实施接口
    Java基础04 封装与接口
    Java基础03 构造器与方法重载
    Java基础02 方法与数据成员
    Java基础01 从HelloWorld到面向对象
    151. Reverse Words in a String
    168. Excel Sheet Column Title
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15148564.html
Copyright © 2011-2022 走看看