ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AT2292 Division into Two

2019-10-30 20:02:40  阅读:280  来源: 互联网

标签:AT2292 Division return int into long isdigit ll getchar


题目
不妨认为\(A>B\)。
首先判一下无解。
设\(f_i\)表示\(A\)集合最后选第\(i\)个数的方案数。
转移的话枚举一下从哪个\(j\)转移过来。
显然\(j\)需要满足以下条件:
\(j<i\)
\(S_j<S_i-A\)
\(\forall a,b\in(j,i)\wedge a<b,S_a<S_b-B\)
不难发现\(j\)的取值范围是一个区间,前缀和优化即可。

#include<cstdio>
#include<cctype>
#define ll long long
ll read(){ll x=0;int c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
const int N=100007,P=1000000007;
int inc(int a,int b){return a+=b,a>=P? a-P:a;}
int dec(int a,int b){return a-=b,a<0? a+P:a;}
int mul(int a,int b){return 1ll*a*b%P;}
ll a[N],f[N],sum[N];
int main()
{
    ll n=read(),A=read(),B=read(),i,l,r,ans=0;
    if(A<B) A^=B^=A^=B;
    for(i=1;i<=n;++i) a[i]=read();
    for(i=1;i+2<=n;++i) if(a[i+2]-a[i]<B) return puts("0"),0;
    f[0]=sum[0]=1,a[n+1]=B+a[n];
    for(i=1,l=r=0;i<=n;++i)
    {
        while(r<i&&a[i]-a[r+1]>=A) ++r;
        if(l<=r) f[i]=inc(f[i],dec(sum[r],l?sum[l-1]:0));
        sum[i]=inc(sum[i-1],f[i]);
        if(i>1&&a[i]-a[i-1]<B) l=i-1;
    }
    for(i=n;~i;--i)
    {
        ans=inc(ans,f[i]);
        if(a[i+1]-a[i]<B) break;
    }
    printf("%d",ans);
}

标签:AT2292,Division,return,int,into,long,isdigit,ll,getchar
来源: https://www.cnblogs.com/cjoierShiina-Mashiro/p/11767330.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有