A |
只需要构造 $2n+2,2n+4,...,4n$ 就可以了。算下来刚好 $n$ 个人。
<
pre class="lang:default decode:true ">#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (vec.begin())
#define veclast (vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
printf("nnTime used:
system("pause");
#endif
}
int n;
inline void solve()
{
cin >> n;
for (int i = 2 * n + 2, tot = 1; tot <= n; ++tot, i += 2)
{
cout << i << " ";
}
}
int main()
{
TIME__START = clock();
int Test = 1;
scanf(
while (Test--)
{
solve();
// if (Test)
// putchar('n');
}
TIME__END = clock();
program_end();
return 0;
}``
B |
贪心。连续的 1 段可以看成一个,问题就在于是把这些 1 段串起来然后一起激活还是每一个 1 段单独激活。连起来的话那么就需要计算串起来所需要的花费,然后从左到右贪心就可以了。
#include#define ll long long #define ls id << 1 #define rs id << 1 | 1 #define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type)) #define memarray(array, value) memset(array, value, sizeof(array)) #define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value) #define fillvector(v, value) fill((v).begin(), (v).end(), value) #define pb(x) push_back(x) #define st(x) (1LL << (x)) #define pii pair #define mp(a, b) make_pair((a), (b)) #define Flush fflush(stdout) #define vecfirst (*vec.begin()) #define veclast (*vec.rbegin()) #define vecall(v) (v).begin(), (v).end() #define vecupsort(v) (sort((v).begin(), (v).end())) #define vecdownsort(v, type) (sort(vecall(v), greater ())) #define veccmpsort(v, cmp) (sort(vecall(v), cmp)) using namespace std; const int N = 500050; const int inf = 0x3f3f3f3f; const ll llinf = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int MOD = 1e9 + 7; const double PI = acos(-1.0); clock_t TIME__START, TIME__END; void program_end() { #ifdef ONLINE printf("nnTime used: system("pause"); #endif } ll n, a, b; string s; inline void solve() { cin >> a >> b >> s; n = s.length(); ll ans = 0, lst = -inf; for (int i = 0; i < n; ++i) { if (s[i] == '1') ans += min(a, b * (i - lst - 1)), lst = i; } cout << ans << 'n'; } int main() { TIME__START = clock(); int Test = 1; scanf( while (Test--) { solve(); // if (Test) // putchar('n'); } TIME__END = clock(); program_end(); return 0; }
C |
将每道菜按照 $a$ 排序,一个显然的贪心就是对于一个特定的 $a_0$,所有 $ale a_0$ 的菜都只需要点外卖即可。剩下的就是 $sum b$,我们可以枚举每一个 $a$,之后可以 $mathcal{O}(1)$ 计算剩下需要自己去买的 $sum b$,所有的情况取最小值就是答案。
#include#define ll long long #define ls id << 1 #define rs id << 1 | 1 #define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type)) #define memarray(array, value) memset(array, value, sizeof(array)) #define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value) #define fillvector(v, value) fill((v).begin(), (v).end(), value) #define pb(x) push_back(x) #define st(x) (1LL << (x)) #define pii pair #define mp(a, b) make_pair((a), (b)) #define Flush fflush(stdout) #define vecfirst (*vec.begin()) #define veclast (*vec.rbegin()) #define vecall(v) (v).begin(), (v).end() #define vecupsort(v) (sort((v).begin(), (v).end())) #define vecdownsort(v, type) (sort(vecall(v), greater ())) #define veccmpsort(v, cmp) (sort(vecall(v), cmp)) using namespace std; const int N = 500050; const int inf = 0x3f3f3f3f; const ll llinf = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int MOD = 1e9 + 7; const double PI = acos(-1.0); clock_t TIME__START, TIME__END; void program_end() { #ifdef ONLINE printf("nnTime used: system("pause"); #endif } int n; ll sumb; struct dishes { ll a, b; bool operator<(const dishes &x) const { return a < x.a; } } d[N]; inline void solve() { sumb = 0; scanf( for (int i = 1; i <= n; ++i) scanf( for (int i = 1; i <= n; ++i) scanf( ll ans = sumb; sort(d + 1, d + n + 1); int i = 1; ll maxa = d[i].a; while (i <= n) { while (d[i].a == maxa) { sumb -= d[i].b; i++; } ans = min(ans, max(maxa, sumb)); maxa = d[i].a; } cout << ans << endl; } int main() { TIME__START = clock(); int Test = 1; scanf( while (Test--) { solve(); // if (Test) // putchar('n'); } TIME__END = clock(); program_end(); return 0; }
D |
如果整个序列都是单调不增或者单调不减的,那么我们就一定能够只操作其中一边来使整个序列减到 0。比如说整个序列是单调不增的,那么我们只需要操作左边就可以。
接下来问题就在于中间不是单调的怎么办。实际上,假设我们最后得到的序列是单调不增的,那么操作右边只会改变交界处的单调性。途中要保证右边的数不能减到小于 0。这样,我们可以两边分别算一下就可以了。代码实现中记录一个增量 delta 即可。
#include#define ll long long #define ls id << 1 #define rs id << 1 | 1 #define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type)) #define memarray(array, value) memset(array, value, sizeof(array)) #define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value) #define fillvector(v, value) fill((v).begin(), (v).end(), value) #define pb(x) push_back(x) #define st(x) (1LL << (x)) #define pii pair #define mp(a, b) make_pair((a), (b)) #define Flush fflush(stdout) #define vecfirst (*vec.begin()) #define veclast (*vec.rbegin()) #define vecall(v) (v).begin(), (v).end() #define vecupsort(v) (sort((v).begin(), (v).end())) #define vecdownsort(v, type) (sort(vecall(v), greater ())) #define veccmpsort(v, cmp) (sort(vecall(v), cmp)) using namespace std; const int N = 500050; const int inf = 0x3f3f3f3f; const ll llinf = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int MOD = 1e9 + 7; const double PI = acos(-1.0); clock_t TIME__START, TIME__END; void program_end() { #ifdef ONLINE printf("nnTime used: system("pause"); #endif } int n; int a[N]; inline void solve() { scanf( for (int i = 1; i <= n; ++i) scanf( int delta = 0; bool solved = 1; for (int i = 2; i <= n; ++i) { if (a[i] > a[i - 1]) delta += a[i] - a[i - 1]; if (a[i] - delta < 0) { solved = 0; break; } } if (solved) return printf("YESn"), void(); delta = 0, solved = 1; reverse(a + 1, a + n + 1); for (int i = 2; i <= n; ++i) { if (a[i] > a[i - 1]) delta += a[i] - a[i - 1]; if (a[i] - delta < 0) { solved = 0; break; } } if (solved) return printf("YESn"), void(); puts("NO"); } int main() { TIME__START = clock(); int Test = 1; scanf( while (Test--) { solve(); // if (Test) // putchar('n'); } TIME__END = clock(); program_end(); return 0; }
E |
一共最多只会跳 2e10 次,算一下发现最多只会变最后 15 项。那么我们可以用康托展开逆变换求出每次操作最后 15 项变成的排列,再重新计算一下 sum 前缀和即可。
#include#define ll long long #define ls id << 1 #define rs id << 1 | 1 #define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type)) #define memarray(array, value) memset(array, value, sizeof(array)) #define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value) #define fillvector(v, value) fill((v).begin(), (v).end(), value) #define pb(x) push_back(x) #define st(x) (1LL << (x)) #define pii pair #define mp(a, b) make_pair((a), (b)) #define Flush fflush(stdout) #define vecfirst (*vec.begin()) #define veclast (*vec.rbegin()) #define vecall(v) (v).begin(), (v).end() #define vecupsort(v) (sort((v).begin(), (v).end())) #define vecdownsort(v, type) (sort(vecall(v), greater ())) #define veccmpsort(v, cmp) (sort(vecall(v), cmp)) using namespace std; const int N = 500050; const int inf = 0x3f3f3f3f; const ll llinf = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int MOD = 1e9 + 7; const double PI = acos(-1.0); clock_t TIME__START, TIME__END; void program_end() { #ifdef ONLINE printf("nnTime used: system("pause"); #endif } int n, q; int a[N], b[20]; ll sum[N]; ll fac[20]; void work(int n, ll k) { int p[20] = {0}; for (int i = 1; i <= n; ++i) b[i] = 0, p[i] = 0; for (int i = 1; i <= n; ++i) { ll t = k / fac[n - i]; k for (int j = 1; j <= n; ++j) { if (!b[j] && !(t--)) { b[j] = 1, p[i] = j; break; } } } int L = max(0, (::n) - 15); for (int i = L + 1; i <= (::n); ++i) sum[i] = sum[i - 1] + p[i - L] + L; } inline void solve() { fac[0] = 1; for (int i = 1; i <= 15; ++i) fac[i] = fac[i - 1] * i; scanf( for (int i = 1; i <= n; ++i) a[i] = i; for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + i; ll k = 0; while (q--) { int op, x, l, r; scanf( if (op == 2) { scanf( k += x; work(min(n, 15), k); } else { scanf( ll ans = sum[r] - sum[l - 1]; printf( } } } int main() { TIME__START = clock(); int Test = 1; // scanf( while (Test--) { solve(); // if (Test) // putchar('n'); } TIME__END = clock(); program_end(); return 0; }
F |
首先把所有需要被打进 b 的位置给标记一下,之后从头开始 check 相邻的位置。每次 check 就看当前这个 $b_i$ 相邻位置上没有被打进 b 的元素个数。因为删除一个相邻位置的数之后,$b_i$ 也被打进 b 了,由于题目保证打进 b 的元素互不相同,那么这个元素打进去之后就没用了,可以理解为极限一换一。于是只需要看相邻的数即可。
#include#define ll long long #define ls id << 1 #define rs id << 1 | 1 #define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type)) #define memarray(array, value) memset(array, value, sizeof(array)) #define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value) #define fillvector(v, value) fill((v).begin(), (v).end(), value) #define pb(x) push_back(x) #define st(x) (1LL << (x)) #define pii pair #define mp(a, b) make_pair((a), (b)) #define Flush fflush(stdout) #define vecfirst (*vec.begin()) #define veclast (*vec.rbegin()) #define vecall(v) (v).begin(), (v).end() #define vecupsort(v) (sort((v).begin(), (v).end())) #define vecdownsort(v, type) (sort(vecall(v), greater ())) #define veccmpsort(v, cmp) (sort(vecall(v), cmp)) using namespace std; const int N = 500050; const int inf = 0x3f3f3f3f; const ll llinf = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int MOD = 1e9 + 7; const double PI = acos(-1.0); clock_t TIME__START, TIME__END; void program_end() { #ifdef ONLINE printf("nnTime used: system("pause"); #endif } int n, k; int a[N], b[N], pos[N], c[N]; inline void solve() { ll ans = 1; scanf( for (int i = 1; i <= n; ++i) scanf( for (int i = 1; i <= k; ++i) scanf( for (int i = 1; i <= k; ++i) { ll fac = 0; fac += ((pos[b[i]] > 1) && (c[pos[b[i]] - 1])) + ((pos[b[i]] < n) && (c[pos[b[i]] + 1])); c[pos[b[i]]] = 1; ans = (ans * fac) } cout << ans << 'n'; } int main() { TIME__START = clock(); int Test = 1; scanf( while (Test--) { solve(); // if (Test) // putchar('n'); } TIME__END = clock(); program_end(); return 0; }
Comments NOTHING