牛客小白月赛49 D(数学) E(DP)

题意:

思路:看一下这个函数f(x),不难发现它是一条开口向下的抛物线,在[a,b]这个范围f(x)>0,所以要求S(n)-S(m)的最大值,即求区间[a,b]这一部分的累加和,即S(n)-S(m)=S(b)-S(a),我们来列出式子,S(n)-S(m)=-(m-a)(m-b)-(m+1-a)(m+1-b)-...-(n-a)(n-b)=-(m^2-(a+b)m+ab)-((m+1)^2-(a+b)(m+1)+ab)-...-(n^2-(a+b)n+ab)=-(m^2+(m+1)^2+...+n^2)-(a+b)(m+(m+1)+..n)-(ab+ab+..+ab)。

公式:1^2+2^2+..+n^2=n(n+1)(2n+1)/6。

所以,m^2+(m+1)^2+...+n^2=n(n+1)(2n+1)/6-(m-1)m(2m-1)/6。

等差公式,m+(m+1)+..n=(m+n)/2*(n-m+1)。

注意:这道题还是有挺多坑的,一个是数据范围,还有一个是取模运算哪里,负数要记得+mod,再取模!!!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod= 998244353;
ll t,a,b;
ll qmi(ll a,ll k)
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*a%mod;
        a=a*a%mod;
        k>>=1;
    }
    return res;
}
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>a>>b;
        ll n=b,m=a;
        ll res=0;
        ll s1=-(n*(n+1)%mod*(2*n+1)%mod*qmi(6,mod-2)%mod-m*(m-1)%mod*(2*m-1)%mod*qmi(6,mod-2)%mod+mod)%mod;
        ll s2=(a+b)*(m+n)%mod*qmi(2,mod-2)%mod*(n-m+1)%mod;
        ll s3=-(a*b%mod*(n-m+1)%mod);
        cout<<((s1+s2+mod)%mod+s3+mod)%mod<<"\n";
    }
    return 0;
}

E 禅

题意:

思路:从终点往两个方向走, f[i]以i为起点走到终点的需要的最小初始值
f[i]=f[i+1]-a[i],因为如果能够经过这个点,那么肯定就要加上这个点的值,所以f[i]=f[i+1]-a[i]
同理向另外一边也是,f[i]=f[i-1]-a[i]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=0x3f3f3f3f;
int a[N],f[N];
int t,n;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int idx;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            //f[i]=0;
            if(a[i]==0) idx=i;
        }
        if(n==1)
        {
            printf("No Solution\n");
            continue;
        }
        f[idx]=0;
        int ans=INF;
        for(int i=idx-1;i>0;i--)
        {
            f[i]=max(f[i+1]-a[i],a[i]+1);
            ans=min(ans,f[i]);
        }
        for(int i=idx+1;i<=n;i++)
        {
            f[i]=max(f[i-1]-a[i],a[i]+1);
            ans=min(f[i],ans);
        }
        printf("%d\n",ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值