栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

牛客月赛49

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

牛客月赛49

本篇题解只是记录我的做题过程代码,不提供最优解
(另外这里所有的时间复杂度都只分析单个样例,不算 t t t的时间复杂度)

D

点击此处查看对应的题目.
本题设计算法:逆元 + 快速幂 + 二次函数性质

本题要求得到两和之差的最大值: 由图像可知,S(b) - S(a - 1) 即为f(x) 的最大值(类似前缀和)。

所以这里我们要求得S(a) 和 S(b),所以,我们要得到求 S 的公式

S ( x ) S(x) S(x) = − ∑ 1 x x 2 + ( a + b ) ∑ 1 x x + ( a ∗ b ) ∑ 1 x 1 -displaystyle sum_{1}^{x}x^2 + (a + b)displaystyle sum_{1}^{x}x +(a * b)displaystyle sum_{1}^{x}1 −1∑x​x2+(a+b)1∑x​x+(a∗b)1∑x​1

分别求和

  • ∑ 1 x x 2 displaystyle sum_{1}^{x}x^2 1∑x​x2:数学归纳法:
  • ∑ 1 x x displaystyle sum_{1}^{x}x 1∑x​x:等差数列求和
  • ∑ 1 x 1 displaystyle sum_{1}^{x}1 1∑x​1:即为 n

最后还需要注意一点:
由于本题需要对答案取模运算,且本题目的求和公式中包含除法取模操作,所以,不能直接取模,被除数直接乘上除数的乘法逆元即可与之等效。

求乘法逆元:由于本题的 mod 值是质数,所以我们可以用快速幂求逆元的方法求出乘法逆元

时间复杂度 O ( l o g n ) O(logn) O(logn)

#include 
#include 
#include 
using namespace std;
typedef long long ll;
const ll N = 1e5 + 10,mod = 998244353;

ll qmi(ll a,ll b) 
{
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}
ll S(ll n,ll a,ll b)
{
    ll x = n * (n + 1ll) % mod * (2ll * n + 1ll) % mod * qmi(6,mod - 2) % mod;
    ll y = (a + b) * n % mod * (n + 1ll) % mod * qmi(2,mod - 2) % mod;
    ll z = a * b % mod * n % mod;
    ll res = (-x + y - z) % mod;
    res = (res + mod) % mod;
    return res;
}
int main()
{
    int t;
    cin >> t;
    while (t -- ) {
        ll a,b;
        cin >> a >> b;
        cout << (S(b,a,b) - S(a - 1,a,b) + mod) % mod << 'n';
    }
    return 0; 
}


E

点击此处查看对应的题目.
本题设计算法:递推 / 思维DP?

本题主要需要通过对比可能的数据,我们可以发现一下特点

  • 每次走一步都必须比原来的数字+1
  • dp[i] = dp[i - 1]/dp[i + 1] - a[i] 的规律(dp[i]表示从第 i 个点开始的最小初始值)

对比数据:
1 2 3 4 0
2 2 1 10 0
2 1 0 1 2

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

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const ll N = 3e6 + 10,INF = 1e18;
ll a[N],dp[N];//dp[i]表示从第 i 个点开始的最小初始值

void solve()
{
    int n,idx;
    cin >> n;
    for (int i = 1;i <= n;i ++ ) {
        scanf("%lld",&a[i]);
        if (!a[i]) idx = i;
    }
    if (n == 1) {
        puts("No Solution");
        return;
    }
    for (int i = 1;i <= n + 5;i ++ ) dp[i] = INF; 
    for (int i = idx - 1;i >= 1; i -- ) {
        dp[i] = a[i] + 1;
        if (i != idx - 1) dp[i] = max(dp[i],dp[i + 1] - a[i]);
    }
    for (int i = idx + 1;i <= n;i ++ ) {
        dp[i] = a[i] + 1;
        if (i != idx + 1) dp[i] = max(dp[i],dp[i - 1] - a[i]);
    }
    ll res = INF;
    for (int i = 1;i <= n;i ++ ) res = min(res,dp[i]);
    cout << res << 'n';
}
int main()
{
    int t;
    cin >> t;
    while (t -- ) solve();
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873266.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号