博主又復活了(因爲文化課作業太多寫不完了所以繼續自爆自棄
A.完全k叉樹
簽到題,考慮最底層的點的距離即可,注意細節(成功拉低了平均通過率)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
int main() {
int T = read();
while (T--) {
LL k = read(), n = read(), x = 1, now = 1, cnt = 0;
if (k == 1) {
printf("%d\n", n - 1);
continue;
}
while (x < n) {
cnt++;
now *= k;
x += now;
}
x -= now;
cnt--;
LL ans = 0, lft = n - x;
if (lft <= now / k) ans = max(cnt * 2 + 1, lft == 1 ? 1LL : 2LL);
else ans = cnt * 2 + 2;
printf("%d\n", ans);
}
return 0;
}
B.距離產生美
簽到題,每次當且僅當時,把改成
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 100010;
int a[N], used[N];
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
int main() {
int n = read(), k = read(), ans = 0;
For(i, 1, n) a[i] = read();
For(i, 2, n) {
if (abs(a[i] - a[i - 1]) < k && !used[i - 1]) {
ans++;
used[i] = 1;
}
}
printf("%d\n", ans);
return 0;
}
C.烤麪包片
簽到題,所以只需考慮的情況,其他都輸出,注意
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
inline int mul(int x, int y, int M) {return (int)(1LL * x * y % M);}
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
int main() {
int n = read(), M = read();
if (n == 0 || n == 1) printf("%d\n", 1 % M);
else if (n == 2) printf("%d\n", 2 % M);
else if (n == 3) {
int now = 1;
For(i, 1, 720) now = mul(now, i, M);
printf("%d\n", now);
}
else puts("0");
return 0;
}
D.茶顏悅色
普通題,將y座標離散對x這一維線性枚舉長度爲k的所有點,對y這一維用掃描線維護只對[y-k,y]有貢獻,時間複雜度(給茶顏悅色打廣告可還行
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int N = 100010;
struct Point {
int x, y;
}p[N];
struct Node {
Node *ls, *rs;
int tag, v;
Node() {
ls = rs = 0;
tag = v = 0;
}
}*root;
int py[N << 1], cnty;
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
inline bool cmp(Point a, Point b) {
return a.x < b.x || a.x == b.x && a.y < b.y;
}
inline void pushdown(Node *&rt) {
if (!rt -> ls) rt -> ls = new Node();
if (!rt -> rs) rt -> rs = new Node();
rt -> ls -> v += rt -> tag;
rt -> rs -> v += rt -> tag;
rt -> ls -> tag += rt -> tag;
rt -> rs -> tag += rt -> tag;
rt -> tag = 0;
}
inline void pushup(Node *&rt) {
rt -> v = max(rt -> ls -> v, rt -> rs -> v);
}
inline void modify(int l, int r, int L, int R, int val, Node *&rt) {
if (!rt) rt = new Node();
if (r < L || R < l) return;
if (L <= l && r <= R) {
rt -> tag += val;
rt -> v += val;
return;
}
int mid = l + r >> 1;
pushdown(rt);
modify(l, mid, L, R, val, rt -> ls);
modify(mid + 1, r, L, R, val, rt -> rs);
pushup(rt);
}
int main() {
int n = read(), k = read();
py[++cnty] = 1;
For(i, 1, n) {
p[i].x = read(), p[i].y = read();
py[++cnty] = p[i].y;
py[++cnty] = p[i].y - k;
}
sort(py + 1, py + cnty + 1);
int ny = unique(py + 1, py + cnty + 1) - py - 1;
sort(p + 1, p + n + 1, cmp);
int l = 1, r = 1;
for(; r <= n; ++r) {
if (p[r].x - p[l].x > k) break;
modify(1, ny, lower_bound(py + 1, py + ny + 1, p[r].y - k) - py, lower_bound(py + 1, py + ny + 1, p[r].y) - py, 1, root);
}
int ans = 0;
for(; r <= n; ++r) {
ans = max(ans, root -> v);
for(; p[r].x - p[l].x > k; ++l) modify(1, ny, lower_bound(py + 1, py + ny + 1, p[l].y - k) - py, lower_bound(py + 1, py + ny + 1, p[l].y) - py, -1, root);
modify(1, ny, lower_bound(py + 1, py + ny + 1, p[r].y - k) - py, lower_bound(py + 1, py + ny + 1, p[r].y) - py, 1, root);
}
ans = max(ans, root -> v);
printf("%d\n", ans);
return 0;
}
E.飛行棋
普通題,考慮在中的每一個位置都有的概率到達終點,還有的概率到達另一個的點,所以期望步數是。從終點出發逆向dp,,由於d較大,使用矩陣加速即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 25;
int K, inv;
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
inline void upd(int &x, int y) {x += y; x -= x >= MOD ? MOD : 0;}
inline int dec(int x, int y) {x -= y; x += x < 0 ? MOD : 0; return x;}
inline int add(int x, int y) {x += y; x -= x >= MOD ? MOD : 0; return x;}
inline int mul(int x, int y) {return 1LL * x * y % MOD;};
inline int qui_pow(int x, int y) {
int ret = 1;
for(; y; y >>= 1) {
if (y & 1) ret = mul(ret, x);
x = mul(x, x);
}
return ret;
}
struct Matrix {
int num[N][N];
Matrix operator * (const Matrix &A) const {
Matrix ret;
memset(ret.num, 0, sizeof ret.num);
For(i, 1, K) For(j, 1, K) For(k, 1, K) upd(ret.num[i][j], mul(num[i][k], A.num[k][j]));
return ret;
}
}init, cha;
inline Matrix mat_pow(Matrix x, LL y) {
Matrix ret;
memset(ret.num, 0, sizeof ret.num);
For(i, 1, K) ret.num[i][i] = 1;
for(; y; y >>= 1) {
if (y & 1) ret = ret * x;
x = x * x;
}
return ret;
}
int main() {
LL d = read();
K = read(), inv = qui_pow(K, MOD - 2);
For(i, 1, K) init.num[1][i] = K, cha.num[i][1] = inv;
init.num[1][K + 1] = cha.num[K + 1][1] = cha.num[K + 1][K + 1] = 1;
For(i, 2, K) cha.num[i - 1][i] = 1;
K++;
init = init * mat_pow(cha, d - K + 1);
printf("%d\n", init.num[1][1]);
return 0;
}
F.三元組
普通題,假設,所以,只需按排序即可,亦然
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 100010;
inline void upd(int &x, int y) {x += y; x -= x >= MOD ? MOD : 0;}
inline int dec(int x, int y) {x -= y; x += x < 0 ? MOD : 0; return x;}
inline int add(int x, int y) {x += y; x -= x >= MOD ? MOD : 0; return x;}
inline int mul(int x, int y) {return 1LL * x * y % MOD;};
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
struct Node {
int a, b, c, v;
}p[N];
int v[N], sum[N], n;
inline bool cmp(Node x, Node y) {return x.v < y.v;}
inline int solve() {
int ret = 0;
For(i, 1, n) p[i].v = 2 * p[i].a - p[i].b;
sort(p + 1, p + n + 1, cmp);
sum[0] = v[0] = 0;
For(i, 1, n) {
v[i] = p[i].v;
sum[i] = add(sum[i - 1], p[i].c);
upd(ret, mul(sum[upper_bound(v + 1, v + i + 1, -v[i]) - v - 1], p[i].c));
}
return ret;
}
int main() {
n = read();
For(i, 1, n) p[i].a = read(), p[i].b = read(), p[i].c = read();
int ans = solve();
For(i, 1, n) swap(p[i].a, p[i].b);
upd(ans, solve());
printf("%d\n", ans);
return 0;
}
G.籃球校賽
簽到題,直接狀壓dp,時間複雜度
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 100010;
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
LL dp[N][32], a[N][5];
int main() {
int n = read();
For(i, 1, n) For(j, 0, 4) a[i][j] = read();
For(i, 1, n) {
For(j, 0, 31) {
For(k, 0, 4) {
if ((j >> k) & 1) dp[i][j] = max(dp[i - 1][j ^ (1 << k)] + a[i][k], dp[i][j]);
dp[i][j] = max(dp[i - 1][j], dp[i][j]);
}
}
}
printf("%lld\n", dp[n][31]);
return 0;
}
H.分配學號
簽到題,先排序確定最終的學號集合,易證明集合是唯一的,從大到小枚舉可能,運用乘法原理和加法原理求得答案
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 100010;
inline void upd(int &x, int y) {x += y; x -= x >= MOD ? MOD : 0;}
inline int dec(int x, int y) {x -= y; x += x < 0 ? MOD : 0; return x;}
inline int add(int x, int y) {x += y; x -= x >= MOD ? MOD : 0; return x;}
inline int mul(int x, int y) {return 1LL * x * y % MOD;}
LL a[N], b[N];
int ans = 1, cnt[N];
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
int main() {
int n = read();
For(i, 1, n) a[i] = read();
sort(a + 1, a + n + 1);
memcpy(b, a, sizeof b);
For(i, 2, n) {
if (a[i] <= a[i - 1]) a[i] = a[i - 1] + 1, cnt[i] = cnt[i - 1] + 1;
}
int now = 0, maxi = 0, ret = 1;
Rep(i, n, 1) {
if (!cnt[i]) {
ans = mul(ans, ret);
now = maxi = 0;
continue;
}
if (!now) now = cnt[i], maxi = a[i], ret = 1;
ret = mul(ret, maxi - b[i] + 1 - now + cnt[i]);
}
printf("%d\n", ans);
return 0;
}
I.Gree的心房
簽到題,留出最短的一條路徑,可見障礙物最多填充個位置,超過這個值就輸出-1,否則輸出n+m-2
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define Mp make_pair
#define Pi pair<int, int>
#define Pb push_back
#define Fi first
#define Se second
#define Gc getchar
#define LL long long
#define Res register int
#define For(i, l, r) for(int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for(int i = (int)(r); i >= (int)(l); --i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
inline LL read(){
LL x = 0;
char ch = Gc();
bool positive = 1;
for (; !isdigit(ch); ch = Gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = Gc()) x = (x << 1) + (x << 3) + (ch ^ 48);
return positive ? x : -x;
}
int main() {
int n = read(), m = read(), k = read();
LL all = 1LL * (n - 1) * (m - 1);
if (k <= all) printf("%d\n", n + m - 2);
else puts("-1");
return 0;
}
比賽總結:jwj是有gf的人生贏家!我也要!