A
直接模拟即可
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
using namespace std;
using i128 = __int128;
using u128 = unsigned __int128;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLD;
const int N = 1e5 + 10, MOD = 998244353;
const int INF = 1e9;
const LL LL_INF = 1e18;
const LD EPS = 1e-8;
const int dx4[] = {-1, 0, 1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1};
istream &operator>>(istream &is, i128 &val) {
string str;
is >> str;
val = 0;
bool flag = false;
if (str[0] == '-') flag = true, str = str.substr(1);
for (char &c: str) val = val * 10 + c - '0';
if (flag) val = -val;
return is;
}
ostream &operator<<(ostream &os, i128 val) {
if (val < 0) os << "-", val = -val;
if (val > 9) os << val / 10;
os << static_cast<char>(val % 10 + '0');
return os;
}
bool cmp(LD a, LD b) {
if (fabs(a - b) < EPS) return 1;
return 0;
}
void solve() {
int x;
cin >> x;
if (x <= 1599) cout << "Rated" << '\n';
else cout << "Unrated" << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
while (T--) solve();
cout << fixed << setprecision(15);
return 0;
}
B

思路就是一直讲铜牌转换为银牌, 直到银牌无法变为金牌为止, 退出循环
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
using namespace std;
using i128 = __int128;
using u128 = unsigned __int128;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLD;
const int N = 1e5 + 10, MOD = 998244353;
const int INF = 1e9;
const LL LL_INF = 1e18;
const LD EPS = 1e-8;
const int dx4[] = {-1, 0, 1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1};
istream &operator>>(istream &is, i128 &val) {
string str;
is >> str;
val = 0;
bool flag = false;
if (str[0] == '-') flag = true, str = str.substr(1);
for (char &c: str) val = val * 10 + c - '0';
if (flag) val = -val;
return is;
}
ostream &operator<<(ostream &os, i128 val) {
if (val < 0) os << "-", val = -val;
if (val > 9) os << val / 10;
os << static_cast<char>(val % 10 + '0');
return os;
}
bool cmp(LD a, LD b) {
if (fabs(a - b) < EPS) return 1;
return 0;
}
void solve() {
int a, b, c, x, y;
cin >> a >> b >> c >> x >> y;
LL cur3 = c, cur2 = b;
LL ans = a;
while (1) {
while (cur3 >= x) {
cur2 += cur3 / x;
cur3 %= x;
}
if (cur2 >= y) {
while (cur2 >= y) {
int v = cur2 / y;
cur2 %= y;
ans += v;
cur3 += v;
}
}
else break;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
while (T--) solve();
cout << fixed << setprecision(15);
return 0;
}
C

注意到每次都是在前缀加上一个数
最终的结果一定是
也就是说最终的序列一定是单调不升的
那么对应的序列也应该单调不升, 为了保证不同数字数量最多, 当前位置填写的数字应该越大越好
记录一个前缀最小值, 也就是当前位置能填写数字的上限
假设当前位置填写的是, 因为前一个数字已经填了
, 那么当前能填写的最大数字就是
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
using namespace std;
using i128 = __int128;
using u128 = unsigned __int128;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLD;
const int N = 1e5 + 10, MOD = 998244353;
const int INF = 1e9;
const LL LL_INF = 1e18;
const LD EPS = 1e-8;
const int dx4[] = {-1, 0, 1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1};
istream &operator>>(istream &is, i128 &val) {
string str;
is >> str;
val = 0;
bool flag = false;
if (str[0] == '-') flag = true, str = str.substr(1);
for (char &c: str) val = val * 10 + c - '0';
if (flag) val = -val;
return is;
}
ostream &operator<<(ostream &os, i128 val) {
if (val < 0) os << "-", val = -val;
if (val > 9) os << val / 10;
os << static_cast<char>(val % 10 + '0');
return os;
}
bool cmp(LD a, LD b) {
if (fabs(a - b) < EPS) return 1;
return 0;
}
void solve() {
int n;
cin >> n;
vector<int> d(n + 1);
for (int i = 1; i <= n; ++i) cin >> d[i];
int minv = INF;
vector<int> b(n + 1);
for (int i = 1; i <= n; ++i) {
if (minv > d[i]) {
b[i] = d[i];
}
else {
b[i] = b[i - 1] - 1;
}
minv = b[i];
if (minv == 0) break;
}
set<int> st;
for (int i = 1; i <= n; ++i) st.insert(b[i]);
cout << st.size() << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) solve();
cout << fixed << setprecision(15);
return 0;
}
D

区间内最大值最小值, 并且差值不超过, 一眼双指针, 用
维护最值的差
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
using namespace std;
using i128 = __int128;
using u128 = unsigned __int128;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLD;
const int N = 1e5 + 10, MOD = 998244353;
const int INF = 1e9;
const LL LL_INF = 1e18;
const LD EPS = 1e-8;
const int dx4[] = {-1, 0, 1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1};
istream &operator>>(istream &is, i128 &val) {
string str;
is >> str;
val = 0;
bool flag = false;
if (str[0] == '-') flag = true, str = str.substr(1);
for (char &c: str) val = val * 10 + c - '0';
if (flag) val = -val;
return is;
}
ostream &operator<<(ostream &os, i128 val) {
if (val < 0) os << "-", val = -val;
if (val > 9) os << val / 10;
os << static_cast<char>(val % 10 + '0');
return os;
}
bool cmp(LD a, LD b) {
if (fabs(a - b) < EPS) return 1;
return 0;
}
void solve() {
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; ++i) cin >> a[i];
LL ans = 0;
map<int, int> mp;
int l = 1;
for (int i = 1; i <= n; ++i) {
mp[a[i]]++;
while (mp.size() > 2 || mp.rbegin()->x - mp.begin()->x > 1) {
mp[a[l]]--;
if (mp[a[l]] == 0) mp.erase(a[l]);
l++;
}
ans += i - l + 1;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) solve();
cout << fixed << setprecision(15);
return 0;
}
E

分析得到可以将区间的所有变为最终情况只剩
个
, 边界条件特判
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
using namespace std;
using i128 = __int128;
using u128 = unsigned __int128;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLD;
const int N = 1e5 + 10, MOD = 998244353;
const int INF = 1e9;
const LL LL_INF = 1e18;
const LD EPS = 1e-8;
const int dx4[] = {-1, 0, 1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1};
istream &operator>>(istream &is, i128 &val) {
string str;
is >> str;
val = 0;
bool flag = false;
if (str[0] == '-') flag = true, str = str.substr(1);
for (char &c: str) val = val * 10 + c - '0';
if (flag) val = -val;
return is;
}
ostream &operator<<(ostream &os, i128 val) {
if (val < 0) os << "-", val = -val;
if (val > 9) os << val / 10;
os << static_cast<char>(val % 10 + '0');
return os;
}
bool cmp(LD a, LD b) {
if (fabs(a - b) < EPS) return 1;
return 0;
}
void solve() {
int n;
string s;
cin >> n >> s;
int cnt0 = 0;
for (char c : s) {
if (c == '0') cnt0++;
}
if (cnt0 == n) {
cout << 0 << '\n';
return;
}
if (cnt0 == 0) {
cout << n << '\n';
return;
}
cout << n - 1 << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) solve();
cout << fixed << setprecision(15);
return 0;
}
F

首先发现直接算方案算不出来, 因此枚举每个回文子串对答案的贡献
假设回文子串是, 对答案的贡献等于
代表前
个位置划分回文子串的方案数,
类似
然后再枚举每个位置是否能成为回文子串, 算法时间复杂度
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
using namespace std;
using i128 = __int128;
using u128 = unsigned __int128;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N = 1e5 + 10, MOD = 998244353;
const int INF = 1e9;
const LL LL_INF = 1e18;
const LD EPS = 1e-8;
const int dx4[] = {-1, 0, 1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy8[] = {-1, 0, 1, -1, 1, -1, 0, 1};
istream &operator>>(istream &is, i128 &val) {
string str;
is >> str;
val = 0;
bool flag = false;
if (str[0] == '-') flag = true, str = str.substr(1);
for (char &c: str) val = val * 10 + c - '0';
if (flag) val = -val;
return is;
}
ostream &operator<<(ostream &os, i128 val) {
if (val < 0) os << "-", val = -val;
if (val > 9) os << val / 10;
os << static_cast<char>(val % 10 + '0');
return os;
}
bool cmp(LD a, LD b) {
if (fabs(a - b) < EPS) return 1;
return 0;
}
void solve() {
int n;
string s;
cin >> n >> s;
s = ' ' + s;
vector<vector<int>> is(n + 1, vector<int>(n + 1, 0));
for (int i = 1; i <= n; ++i) is[i][i] = 1;
for (int i = n - 1; i >= 1; --i) {
for (int j = i + 1; j <= n; ++j) {
if (s[i] == s[j]) {
if (j - i == 1) is[i][j] = 1;
else is[i][j] = is[i + 1][j - 1];
}
else is[i][j] = 0;
}
}
vector<LL> f(n + 1), g(n + 2);
f[0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= i; ++j) {
if (is[j][i]) {
f[i] = (f[i] + f[j - 1]) % MOD;
f[i] %= MOD;
}
}
}
g[n + 1] = 1;
for (int i = n; i > 0; --i) {
for (int j = i; j <= n; ++j) {
if (is[i][j]) {
g[i] = (g[i] + g[j + 1]) % MOD;
g[i] %= MOD;
}
}
}
LL ans = 0;
for (int i = 1; i <= n; ++i) {
for (int j = i; j <= n; ++j) {
if (is[i][j]) {
LL v = f[i - 1] * g[j + 1] % MOD * (j - i + 1) % MOD * (j - i + 1) % MOD;
ans = (ans + v) % MOD;
}
}
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) solve();
cout << fixed << setprecision(15);
return 0;
}

京公网安备 11010502036488号