"蔚来杯"2022牛客暑期多校训练营9
[题目链接]("蔚来杯"2022牛客暑期多校训练营9_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com))
A Car Show
题目大意
给定一个长为n的序列,包含1,2,…,m,求有多少区间[L,R]包含所有1,2,…,m。
题解
思维题。
假设满足条件的第一个区间是[1,R1],那么[1,R](R>=R1)一定满足条件。然后求[2,R2]的R2,此区间的左端点只比[1,R1],少一个T[1],所以可以只考虑下一个T[1]在哪个位置即可。如果位置序号<=R1,那么R2=R1,否则R2=位置序号。依此类推。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
ll n, m, r, res;
ll a[maxn];
map<ll, vector<ll>> mp;
map<ll, ll> mp2;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (ll i = 1; i <= n; i++)
{
cin >> a[i];
mp[a[i]].push_back(i);
}
ll i;
for (i = 1; i <= n; i++)
{
mp2[a[i]]++;
if (mp2.size() == m)
{
r = i;
break;
}
}
if (i > n)
{
cout << 0 << endl;
return 0;
}
res += n - r + 1;
for (ll i = 2; i <= n; i++)
{
auto temp = upper_bound(mp[a[i - 1]].begin(), mp[a[i - 1]].end(), i - 1);
if (temp == mp[a[i - 1]].end())
break;
if (*temp <= r)
{
res += n - r + 1;
}
else
{
r = *temp;
res += n - r + 1;
}
}
cout << res << endl;
return 0;
}
B Two Frogs
题目大意
河道里有n个荷叶排成一排,从第i(<n)个荷叶出发可以跳到第(i,i+ai]个荷叶上。有两只青蛙从第1个荷叶出发,每一步都独立地等概率随机地跳向后边的荷叶,求两只青蛙以相同步数到达第n个荷叶的概率。
题解
动态规划。
dp[i] [j]表示当前位置为i,走了j步时到达点n的概率。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 8e3 + 5;
const int mod = 998244353;
int n, res;
int a[maxn], b[maxn];
int dp[maxn][maxn], sum[maxn][maxn];
ll qpow(ll a, ll n, ll mod)
{
ll res = 1;
while (n)
{
if (n & 1)
res = (res * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return res;
}
ll inv(ll a, ll p)
{
return qpow(a, p - 2, p);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i < n; i++)
{
cin >> a[i];
b[i] = inv(a[i], mod);
}
dp[n][0] = 1;
for (int i = 1; i <= n; i++)
sum[i][0] = 1;
for (int i = n - 1; i >= 1; i--)
{
for (int j = 1; j <= n - i; j++)
{
dp[i][j] = 1ll * (dp[i][j] + sum[i + 1][j - 1] - sum[i + a[i] + 1][j - 1]) * 1ll * b[i] % mod;
sum[i][j] = 1ll * (sum[i + 1][j] + dp[i][j]) % mod;
}
}
for (int i = 1; i <= n; i++)
{
res = (res + 1ll * dp[1][i] * dp[1][i]) % mod;
}
cout << res << endl;
return 0;
}