AtCoder Beginner Contest 230(EF)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 230(EF)相关的知识,希望对你有一定的参考价值。
E - Fraction Floor Sum
题意:
求 ∑ i = 1 n [ n i ] \\sum \\limits_i=1 ^n[\\fracni] i=1∑n[in]
思路:
整除分块板子题
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll F(ll n)
ll res = 0;
for (ll l = 1, r; l <= n; l = r + 1)
r = n / (n / l);
res += (r - l + 1) * (n / l);
return res;
int main()
ll a, b;
cin >> b;
ll res = F(b) - F(0);
cout << res << endl;
F - Predilection
题意:
给定长度为 N N N的数组 A A A,你可以进行任意次操作,操作为删除两个相邻的数字,并把相邻的数字相加并放到原数组的对应位置中,问进行任意次操作,会产生多少种序列?
思路:
f
(
i
)
f(i)
f(i)定义为,到前
i
i
i个位置为止进行操作产生的序列数。
s
u
m
i
=
∑
j
=
1
i
sum_i=\\sum \\limits_j=1 ^i
sumi=j=1∑i,假设原序列中,在合并过程中不会产生重复的序列,那么
f
(
i
)
=
2
∗
f
(
i
−
1
)
f(i)=2*f(i-1)
f(i)=2∗f(i−1),但是在结合的过程中,可能会出现中间某一段是
0
0
0的情况,这样的话,
s
u
m
i
=
s
u
m
j
sum_i=sum_j
sumi=sumj,这就代表着
(
j
,
i
]
(j,i]
(j,i]这段和为0,这样的话,这个
0
0
0往左结合和往右结合是一样的序列,所以会算重复情况,所以对于每个
i
i
i,找到左边下标最大的
j
j
j,且
s
u
m
i
=
s
u
m
j
sum_i=sum_j
sumi=sumj,这样的话,就需要让减去
f
(
j
)
f(j)
f(j)
总结一下,就是,对于情况
j
−
−
−
−
−
−
i
−
1
j------i-1
j−−−−−−i−1
i
i
i
如果
s
u
m
j
=
s
u
m
i
−
1
sum_j=sum_i-1
sumj=sumi−1的话,就是
f
(
i
)
减
去
f
(
j
)
f(i)减去f(j)
f(i)减去f(j)
#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int mod = 998244353;
ll dp[200007];
ll sum[200007];
map<ll, int> mp;
int main()
int n;
cin >> n;
for (int i = 1; i <= n; i++)
int a;
cin >> a;
sum[i] = sum[i - 1] + a;
ll temp = 1;
for (int i = 1; i <= n; i++)
dp[i] = temp % mod;
(temp *= 2) %= mod;
(temp += mod - mp[sum[i]]) %= mod;
mp[sum[i]] = dp[i];
cout << dp[n] << endl;
return 0;
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激
以上是关于AtCoder Beginner Contest 230(EF)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解