天坑。。。php
杭電html
dls代碼:https://ideone.com/Wo55gijava
官方題解:http://bestcoder.hdu.edu.cn/blog/node
2018 Multi-University Training Contest 1ios
1001 Maximum Multiplec++
打表找規律,發現只有當n是3倍數或者4倍數時纔有解git
並且當n%3 == 0,max(x*y*z) = (n/3) * (n/3) * (n/3) = n^3 / 27,數組
當n%4 == 0, max(x*y*z) = (n/2) * (n/4) * (n/4) = n^3 / 32。app
正解是解不定方程組less
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); if(n % 3 == 0) printf("%lld\n", 1LL * n * n * n / 27); else if(n % 4 == 0)printf("%lld\n", 1LL * n * n * n / 32); else printf("-1\n"); } return 0; }
1002 Balanced Sequence
思路:貪心,先把每一個括號序列用棧來使得中間的都括號都匹配,使得右括號都在左邊,左括號都在右邊
而後排序,咱們先把右括號小於等於左括號的排在前面,而後對於右括號小於等於左括號的狀況,咱們按
右括號從小到大排序(由於最左邊的右括號都是被浪費掉的,浪費的越小越好),而後把右括號大於左括
號的狀況排在後面,對於後面這種狀況,咱們按左括號從大到小排序(由於最右邊的左括號都是被浪費掉
的,浪費的越小越好)。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; struct node { int l, r; bool operator < (const node &t) const { if(r <= l && t.r > t.l) return true; if(r > l && t.r <= t.l) return false; if(r <= l && t.r <= t.l) return r < t.r; if(r > l && t.r > t.l) return l > t.l; } }a[N]; char s[N]; int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); int ans = 0; for (int i = 0; i < n; i++) { scanf("%s", s); int l = 0, r = 0; for (int j = 0; j < strlen(s); j++) { if(s[j] == '(') l++; else { if(l) l--, ans += 2; else r++; } } a[i].l = l; a[i].r = r; } sort(a, a+n); int now = a[0].l; for (int i = 1; i < n; i++) { if(a[i].r >= now) { ans += now*2; now = 0; } else { ans += a[i].r*2; now -= a[i].r; } now += a[i].l; } printf("%d\n", ans); } return 0; }
1003 Triangle Partition
1004 Distinct Values
1005 Maximum Weighted Matching
1006 Period Sequence
1007 Chiaki Sequence Revisited
思路:打表找規律,發現每一個數i出現了lowbit(i)的長度次,而後二分最後a[n]的值,複雜度nlog(n)*log(n),會TLE,而後發現,a[n] -> n/2,因此將二分區間改成[n/2, n/2+100]下降複雜度
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 1e9 + 7; const int inv = 5e8 + 4; LL cal(LL m) { LL ans = 0; for (int i = 0; i <= 60; i++) { LL cnt = m / (1LL << i); if(cnt == 0) break; ans += cnt; } return ans; } LL sum(LL m) { LL ans = 0; for (int i = 0; i <= 60; i++) { LL tot = 1LL << i; LL cnt = m / tot; if(cnt == 0) break; LL t = ((cnt % MOD * ((cnt + 1) % MOD)) % MOD * inv) % MOD; t = (t * (tot % MOD) % MOD) % MOD; ans = (ans + t) % MOD; } return ans; } int main() { int T; LL n; scanf("%d", &T); while(T--) { scanf("%lld", &n); if(n <= 2) { printf("%lld\n", n); continue; } n--; LL l = n/2, r = (n/2)+100, m = (l + r) >> 1; while(l < r) { if(cal(m) >= n) r = m; else l = m + 1; m = (l + r) >> 1; } LL tot = cal(m-1); LL res = n - tot; LL ans = (res % MOD * (m % MOD)) % MOD; ans = (ans + sum(m-1) + 1) % MOD; ans = (ans + MOD) % MOD; printf("%lld\n", ans); } return 0; }
1008 RMQ Similar Sequence
1009 Lyndon Substring
1010 Turn Off The Light
1011 Time Zone
2018 Multi-University Training Contest 2
1001 Absolute
1003 Cover
思路:將度數爲奇數的點兩兩相連,而後跑歐拉圖
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<pii>g[N]; bool nodevs[N], edgevs[2*N]; int deg[N], cnt = 0, t, st; vector<int>vc, vcc; vector<int>ans[N]; void dfs(int u) { nodevs[u] = true; if(deg[u]&1) vc.pb(u), st = u; cnt++; for (int i = 0; i < g[u].size(); i++) { if(!nodevs[g[u][i].fi]) { dfs(g[u][i].fi); } } } void add() { for (int i = 0; i < vc.size(); i += 2) { g[vc[i]].pb({vc[i+1], t}); g[vc[i+1]].pb({vc[i], t}); t++; } } void DFS(int u) { for (int i = 0; i < g[u].size(); i++) { if(!edgevs[abs(g[u][i].se)]) { edgevs[abs(g[u][i].se)] = true; DFS(g[u][i].fi); vcc.pb(g[u][i].se); } } } void debug() { for (int i = 0; i < vcc.size(); i++) cout << vcc[i] << " "; cout << endl; } int main() { int n, m, u, v; while(~scanf("%d%d", &n, &m)) { mem(nodevs, false); mem(edgevs, false); mem(deg, 0); for (int i = 0; i <= n; i++) g[i].clear(); for (int i = 1; i <= m; i++) { ans[i].clear(); scanf("%d%d", &u, &v); g[u].pb({v, -i}); g[v].pb({u, i}); deg[u]++; deg[v]++; } int tot = 0; t = m+1; for (int i = 1; i <= n; i++) { if(!nodevs[i]) { cnt = 0; st = i; vc.clear(); dfs(i); if(cnt == 1) continue; add(); vcc.clear(); DFS(st); //debug(); int s = 0, sz = vcc.size(); if(vc.size() > 1) { while(abs(vcc[s]) <= m) { s++; } } else tot++; for (int i = s; i < s+sz; i++) { if(abs(vcc[i%sz]) > m) tot++; else ans[tot].pb(vcc[i%sz]); } } } printf("%d\n", tot); for (int i = 1; i <= tot; i++) { printf("%d ", ans[i].size()); for (int j = 0; j < ans[i].size(); j++) printf("%d%c", ans[i][j], " \n"[j==ans[i].size()-1]); } } return 0; }
1004 Game
思路:考慮將遊戲變成初始時只有2~n,若是先手必勝的話,那麼先手第一步按這樣取就獲勝了;若是後手必勝的話,那麼先手第一步取走1就獲勝了。
因此不管前後手Alice必勝。
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { int n; while(cin >> n) puts("Yes"); return 0; }
1005 Hack It
思路:數論構造
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 3e3 + 100; int a[N][N], p = 47; int main() { fio; cout << 2000 << endl; for (int i = 0; i < p; i++) { for (int j = 0; j < p; j++) { for (int k = 0; k < p; k++) { a[i*p+j][k*p+(i+k*j)%p] = 1; } } } for (int i = 0; i < 2000; i++) { for (int j = 0; j < 2000; j++) printf("%d", a[i][j]); printf("\n"); } return 0; }
1006 Matrix
1007 Naive Operations
思路:考慮只有當ai 爲 bi 倍數時i這個位置才須要被更新,因而咱們倒着減bi,當bi被減成0是,咱們在i這個位置+1,從新將bi設爲原來的bi
判斷bi爲不爲0用線段樹維護,答案用樹狀數組維護,複雜爲nlog(n)^2,由於調和級數的和約爲n*ln(n),因此最多更新nlog(n)次
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int INF = 0x3f3f3f3f; int b[N]; int mn[N*4], lazy[N*4], n; LL bit[N]; vector<int>vc; void add(int x) { while(x <= n) bit[x]++, x += x&-x; } LL sum(int x) { LL ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } void push_up(int rt) { mn[rt] = min(mn[rt<<1], mn[rt<<1|1]); } void push_down(int rt) { lazy[rt<<1] += lazy[rt]; lazy[rt<<1|1] += lazy[rt]; mn[rt<<1] += lazy[rt]; mn[rt<<1|1] += lazy[rt]; lazy[rt] = 0; } void build(int rt, int l, int r) { if(l == r) { lazy[rt] = 0; mn[rt] = b[l]; return ; } lazy[rt] = 0; int m = (l + r) >> 1; build(ls); build(rs); push_up(rt); } void update(int L, int R, int rt, int l, int r, int d) { if(L <= l && r <= R) { mn[rt] += d; if(mn[rt] == 0) { if(l == r) { vc.pb(l); } else { if(lazy[rt]) push_down(rt); int m = (l + r) >> 1; update(L, R, ls, d); update(L, R, rs, d); } } else lazy[rt] += d; return ; } if(lazy[rt]) push_down(rt); int m = (l+r) >> 1; if(L <= m)update(L, R, ls, d); if(R > m) update(L, R, rs, d); push_up(rt); } int query(int L, int R, int rt, int l, int r) { if(L <= l && r <= R) return mn[rt]; int ans = INF; int m = (l+r) >> 1; if(L <= m) ans = min(ans, query(L, R, ls)); if(R > m) ans = min(ans, query(L, R, rs)); return ans; } int main() { fio; string s; int q, l, r; while(cin >> n >> q) { for (int i = 1; i <= n; i++) cin >> b[i]; for (int i = 0; i <= n; i++) bit[i] = 0; build(1, 1, n); for (int i = 1; i <= q; i++) { cin >> s >> l >> r; if(s == "add") { update(l, r, 1, 1, n, -1); if(vc.size() > 0) { //cout << vc.size() << endl; for (int j = 0; j < vc.size(); j++) { add(vc[j]); update(vc[j], vc[j], 1, 1, n, b[vc[j]]); } vc.clear(); } } else { cout << sum(r) - sum(l-1) << endl; } } } return 0; }
1008 Odd Shops
1009 Segment
1010 Swaps and Inversions
思路:求個逆序數,再乘以最小花費
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<int>vc; int a[N], bit[N], n; void add(int x) { while(x <= n) bit[x] ++, x += x&-x; } int sum(int x) { int ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } int main() { int x, y; while(~ scanf("%d %d %d", &n, &x, &y)) { vc.clear(); for (int i = 0; i <= n; i++) bit[i] = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); vc.pb(a[i]); } sort(vc.begin(), vc.end()); vc.erase(unique(vc.begin(), vc.end()), vc.end()); for (int i = 1; i <= n; i++) { a[i] = lower_bound(vc.begin(), vc.end(), a[i]) - vc.begin() +1; } LL tot = 0, ans; for (int i = 1; i <= n; i++) { tot += i - 1 - sum(a[i]); add(a[i]); } ans = min(x, y) * tot; printf("%lld\n", ans); } return 0; }
2018 Multi-University Training Contest 3
1001 Problem A. Ascending Rating
思路:考慮到從前日後維護單調隊列,維護的是單調遞減的序列,與題目不符,因而咱們從後往前維護單調隊列,這樣單調遞減就變成單調遞增了
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e7 + 5; int a[N], nxt[N], tot[N]; int MOD; int main() { int T, n, m, k, p, q, r; scanf("%d", &T); while(T--) { scanf("%d%d%d%d%d%d%d", &n, &m, &k, &p, &q, &r, &MOD); for (int i = 1; i <= k; i++) scanf("%d", &a[i]); for (int i = k+1; i <= n; i++) a[i] = (1LL * p * a[i-1] + 1LL * q * i + r) % MOD; LL A = 0, B = 0; deque<int>q; for (int j = n; j >= 1; j--) { while(!q.empty() && a[q.back()] <= a[j]) q.pop_back(); q.push_back(j); while(!q.empty() && q.front() > j + m - 1) q.pop_front(); if(j <= n-m+1) { //cout << a[q.front()] << " " << q.size() << endl; A += a[q.front()] ^ j; B += ((int)q.size()) ^ j; } } printf("%lld %lld\n", A, B); } return 0; }
1002 Problem B. Cut The String
1003 Problem C. Dynamic Graph Matching
思路:狀壓dp
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 1e9 + 7; char s[15]; int dp[2][1100][10]; int n, m; int main() { int T, u, v; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); int now = 0; mem(dp, 0); for (int i = 0; i < (1<<n); i++) dp[now][i][0] = 1; while(m--) { scanf("%s %d %d", s, &u, &v); now ^= 1; int flag; if(s[0] == '+') flag = 1; else flag = -1; int mx = 0; for (int i = 0; i < (1<<n); i++) { dp[now][i][0] = 1; for (int j = 1; j <= n/2; j++) { if((i|(1<<u-1)|(1<<v-1)) == i)dp[now][i][j] = (dp[now^1][i][j] + flag * dp[now^1][i^(1<<u-1)^(1<<v-1)][j-1]) % MOD; else dp[now][i][j] = dp[now^1][i][j]; } } for (int i = 1; i <= n/2; i++) printf("%d%c", (dp[now][(1<<n)-1][i] + MOD) % MOD, " \n"[i==n/2]); } } return 0; }
1004 Problem D. Euler Function
1005 Problem E. Find The Submatrix
1007 Problem G. Interstellar Travel
1008 Problem H. Monster Hunter
1009 Problem I. Random Sequence
1010 Problem J. Rectangle Radar Scanner
1011 Problem K. Transport Construction
思路:構造
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) #p using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head char s[100][100]; int main() { int T, a, b, c; scanf("%d", &T); while(T--) { scanf("%d%d%d", &a, &b, &c); int n = (c+b) * 2 + 1; int m = (a+b) * 2 + 1; for (int i = 1; i <= n; i++) { if(i&1){ for (int j = 1; j <= m; j++) { if(j&1)s[i][j] = '+'; else s[i][j] = '-'; } } else { for (int j = 1; j <= m; j++) { s[i][j] = '.'; } } } for (int i = 1; i <= 2*b; i++) { for (int j = 1; j <= 2*b - i + 1; j++) { s[i][j] = '.'; s[n-i+1][m-j+1] = '.'; } } for (int i = 2*b + 2; i <= n; i += 2) { for (int j = 1; j <= 2*a; j += 2) { s[i][j] = '|'; } } int st = 2*b+2, ed = n; for (int i = 2*a + 1; i <= m; i += 2) { for (int j = st; j <= ed; j += 2) { s[j][i] = '|'; s[j][i+1] = '/'; s[j-1][i+1] = '.'; } st -= 2; ed -= 2; } for (int i = 2; i <= 2*b; i += 2) { for (int j = 2*b - i + 2; j <= 2*b - i + 2 + 2*a; j += 2) { s[i][j] = '/'; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar(s[i][j]); } puts(""); } } return 0; }
2018 Multi-University Training Contest 4
1001 Problem A. Integers Exhibition
1002 Problem B. Harvest of Apples
思路:
咱們打表發現組合數的和 和 組合數的遞推 是同樣的:sum(n, m) = sum(n-1, m) + sum(n-1, m-1)
對N進行分塊,先預處理出每i*√N行的值,而後對於每一個sum(n, m)咱們都能在O(√N)時間之內遞推出它的值
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5, M = 350; const int MOD = 1e9 + 7; int blo = sqrt(N); vector<int>c[M]; int C[M][M], inv[N], tot = 0; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } void init() { int cnt = 1; inv[1] = 1; for (int i = 2; i < N; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD; for (int i = 1; i < N; i += blo) { c[cnt].resize(i+blo+5); c[cnt][0] = 1; LL t = 1; for (int j = 1; j <= i; j++) { tot++; t = (t * (i-j+1)) % MOD; t = (t * inv[j]) % MOD; c[cnt][j] = (c[cnt][j-1] + t) % MOD; } for (int j = i+1; j <= i+blo; j++) c[cnt][j] = c[cnt][i]; cnt++; } C[0][0] = 1; for (int i = 1; i < M; i++) { for (int j = 1; j <= i; j++) C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD; } } int main() { init(); int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); int bl = (n-1)/blo; int base = bl*blo + 1; int dis = n - base + 1; int l = m - dis + 1, r = m; LL ans = 0; for (int i = l, j = 1; i <= r; i++, j++) { if(i < 0) continue; ans = (ans + 1LL*C[dis][j]*c[bl+1][i]%MOD) % MOD; } printf("%lld\n", ans); } return 0; }
1003 Problem C. Problems on a Tree
1004 Problem D. Nothing is Impossible
思路:
貪心
若是僅有 1 道題,至少有一我的作對這題須要有 錯誤答案個數 + 1 我的。
咱們將題目按錯誤答案個數從小到大排序,從錯誤答案個數小的開始回來,看最多回答了幾個問題後存在1我的全對。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 222; pii a[N]; bool cmp(pii a, pii b) { return a.se < b.se; } int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d %d", &a[i].fi, &a[i].se); } sort(a, a+n, cmp); int ans = 0; for (int i = 0; i < n; i++) { if(m >= 1 + a[i].se) { m = floor((double)m / (1 + a[i].se)); if(m >= 1) ans++; } } printf("%d\n", ans); } return 0; }
1005 Problem E. Matrix from Arrays
思路:咱們發現當n爲奇數時是以n*n爲循環,當n爲偶數時是以2n * 2n爲循環
因而咱們打好2n * 2n的表,算好前綴和,注意處理好邊界
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e3 + 5; int M[N][N], A[N]; LL sum[N][N] = {0}; int main() { fio; int T; cin >> T; while(T--) { int cursor = 0, n, q, x, y, x1, y1; cin >> n; for (int i = 0; i < n; i++) cin >> A[i]; for (int i = 0; i < 10*n; ++i) { for (int j = 0; j <= i; ++j) { M[j+1][i - j+1] = A[cursor]; cursor = (cursor + 1) % n; } } /*for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cout << M[i][j] << " "; } cout<< endl; }*/ for (int i = 1; i <= 4*n; i++) { for (int j = 1; j <= 4*n; j++) { sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + M[i][j]; } } cin >> q; while(q--) { cin >> x >> y >> x1 >> y1; x++, y++, x1++, y1++; int h = (x1 - x + 1); int w = (y1 - y + 1); LL ans = 0; ans = 1LL * (w/(2*n)) * (h/(2*n)) * sum[2*n][2*n]; int w1 = w%(2*n); int h1 = h%(2*n); int xx = x%(2*n); int yy = y%(2*n); if(xx == 0) xx += 2*n; if(yy == 0) yy += 2*n; LL s1, s2, s3; if(w1) { int xxx = xx + 2*n - 1, yyy = yy + w1 - 1; s1 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1]; } else s1 = 0; if(h1) { int xxx = xx + h1 - 1, yyy = yy + 2*n - 1; s2 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1]; } else s2 = 0; if(w1 && h1) { int xxx = xx + h1 - 1, yyy = yy + w1 - 1; s3 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1]; } else s3 = 0; ans += s1*(h/(2*n)) + s2 * (w/(2*n)) + s3; cout << ans << endl; } } return 0; }
1006 Problem F. Travel Through Time
1007 Problem G. Depth-First Search
1008 Problem H. Eat Cards, Have Fun
1009 Problem I. Delightful Formulas
1010 Problem J. Let Sudoku Rotate
思路:搜索剪枝
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 100; char s[N][N]; int g[N][N]; int t[N][N], ans; bool vis[16]; void Rotate(int x, int y) { for (int i = 1, a = y; i <= 4; i++, a++) { for (int j = 1, b = x+3; j <= 4; j++, b--) { t[i][j] = g[b][a]; } } for (int i = 1, a = x; i <= 4; i++, a++) { for (int j = 1, b = y; j <= 4; j++, b++) { g[a][b] = t[i][j]; } } } bool check(int x, int y) { for (int i = 1; i <= x; i++) { mem(vis, false); for (int j = 1; j <= y; j++) { if(vis[g[i][j]]) return false; else vis[g[i][j]] = true; } } for (int j = 1; j <= y; j++) { mem(vis, false); for (int i = 1; i <= x; i++) { if(vis[g[i][j]]) return false; else vis[g[i][j]] = true; } } return true; } void dfs(int pos, int tot) { if(pos == 16) { ans = min(ans, tot); return ; } for (int i = 0; i < 4; i++) { if(check(pos/4*4+4, pos%4*4+4)) dfs(pos+1, tot+i); Rotate(pos/4*4+1, pos%4*4+1); } } int main() { int T; scanf("%d", &T); while(T--) { for (int i = 1; i <= 16; i++) { scanf("%s", s[i]+1); } for (int i = 1; i <= 16; i++) { for (int j = 1; j <= 16; j++) { if(isdigit(s[i][j])) g[i][j] = s[i][j] - '0'; else g[i][j] = s[i][j] - 'A' + 10; } } ans = 16*3; dfs(0, 0); printf("%d\n", ans); } return 0; }
1011 Problem K. Expression in Memories
思路:模擬
隊友代碼
#include<bits/stdc++.h> using namespace std; typedef long long ll; bool check(char ch) { if(ch=='+'||ch=='*') return true; return false; } int main() { int n; scanf("%d",&n); while(n--) { string s; cin>>s; int len=s.size(); int ok=1; int flag=0; for(int i=0;i<len;i++) { if(i==0&&s[i]=='0'&&!check(s[i+1])&&i+1<len) { if(s[i+1]=='?') s[i+1]='+'; else { ok=0; break; } } if(check(s[i])&&s[i+1]=='0'&&!check(s[i+2])&&i+2<len) { if(s[i+2]=='?') s[i+2]='+'; else { ok=0; break; } } if(s[i]=='?') s[i]='5'; else if(check(s[i])&&check(s[i+1])) { ok=0; break; } } if(check(s[0])||check(s[len-1])) ok=0; if(!ok) printf("IMPOSSIBLE\n"); else cout<<s<<endl; } }
1012 Problem L. Graph Theory Homework
思路:
容易證實floor(sqrt(a)) + floor(sqrt(b)) > floor(sqrt(a+b))
因此最短路就是從1走到n
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e5 + 5; int a[N]; int main() { int n, T; scanf("%d", &T); while(T--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); printf("%d\n", (int)sqrt(abs(a[1] - a[n]))); } return 0; }
2018 Multi-University Training Contest 5
1001 Always Online
1002 Beautiful Now
思路:暴力搜索
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head string s, a, b, ansmn, ansmx; int n, k; void dfs(int pos, int cnt) { if(cnt > k) return ; if(pos == n) { ansmn = min(ansmn, a); ansmx = max(ansmx, a); return ; } for (int i = pos; i < n; i++) { if(i == pos) { if(pos == 0 && a[i] == '0'); else { dfs(pos+1, cnt); } } else { if(pos == 0 && a[i] == '0'); else { swap(a[i], a[pos]); dfs(pos+1, cnt+1); swap(a[i], a[pos]); } } } } int main() { fio; int T; cin >> T; while(T--) { cin >> s >> k; n = s.size(); if(k >= n-1) { sort(s.begin(), s.end()); a = s; reverse(s.begin(), s.end()); b = s; for (int i = 0; i < n; i++) { if(a[i] != '0') { swap(a[0], a[i]); break; } } cout << a << " " << b << endl; } else { a = s; ansmn = a; ansmx = a; dfs(0, 0); cout << ansmn << " " << ansmx << endl; } } return 0; }
1004 Daylight
思路:餘弦定理
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head int main() { int T, m; double R, x, y, r; scanf("%d", &T); while(T--) { scanf("%d %lf", &m, &R); double ans = 2 * pi * R; while(m--) { scanf("%lf %lf %lf", &x, &y, &r); double dd = x*x + y*y; if(sqrt(dd) > R + r || sqrt(dd) < R - r) continue; double sub = acos((R*R + dd - r*r) / (2*R*sqrt(dd))); double pls = acos((r*r + dd - R*R) / (2*r*sqrt(dd))); ans -= 2*sub*R; ans += 2*pls*r; } printf("%.10f\n", ans); } return 0; }
1006 Fireflies
1007 Glad You Came
思路:線段樹剪枝或者st表逆運用
線段樹(700ms)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 1 << 30; int tree[N<<2], lazy[N<<2]; unsigned int X, Y, Z, t[5]; inline unsigned int f() { X ^= X << 11; X ^= X >> 4; X ^= X << 5; X ^= X >> 14; unsigned int W = X ^ (Y ^ Z); X = Y; Y = Z; Z = W; return Z; } inline void push_up(int rt) { tree[rt] = min(tree[rt<<1], tree[rt<<1|1]); } inline void push_down(int rt) { tree[rt<<1|1] = max(lazy[rt], tree[rt<<1|1]); tree[rt<<1] = max(lazy[rt], tree[rt<<1]); lazy[rt<<1|1] = max(lazy[rt], lazy[rt<<1|1]); lazy[rt<<1] = max(lazy[rt], lazy[rt<<1]); lazy[rt] = 0; } void build(int rt, int l, int r) { if(l == r) { tree[rt] = lazy[rt] = 0; return ; } lazy[rt] = tree[rt] = 0; int m = l+r >> 1; build(ls); build(rs); } inline void update(int L, int R, int v, int rt, int l, int r) { if(tree[rt] >= v) return ; if(L <= l && r <= R) { if(tree[rt] >= v) return ; else { if(l == r) tree[rt] = v, lazy[rt] = v; else { if(lazy[rt] < v) lazy[rt] = v; } return ; } } if(lazy[rt]) push_down(rt); int m = l+r >> 1; if(L <= m) update(L, R, v, ls); if(R > m) update(L, R, v, rs); push_up(rt); } inline int query(int p, int rt, int l, int r) { if(l == r) return tree[rt]; if(lazy[rt]) push_down(rt); int m = l+r >> 1; if(p <= m) return query(p, ls); else return query(p, rs); } int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z); build(1, 1, n); for (int i = 1; i <= m; i++) { for (int j = 1; j <= 3; j++) t[j] = f(); int l = min(t[1]%n + 1, t[2]%n + 1); int r = max(t[1]%n + 1, t[2]%n + 1); int v = t[3] % MOD; update(l, r, v, 1, 1, n); } LL ans = 0; for (int i = 1; i <= n; i++) { int t = query(i, 1, 1, n); ans ^= (1LL * i * t); } printf("%lld\n", ans); } return 0; }
st表(2200ms)跑的比個人線段樹慢多了
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 10; const int MOD = 1 << 30; int st[N][20], Log[N]; unsigned int X, Y, Z, t[5]; inline unsigned int f() { X ^= X << 11; X ^= X >> 4; X ^= X << 5; X ^= X >> 14; unsigned int W = X ^ (Y ^ Z); X = Y; Y = Z; Z = W; return Z; } void init(int n) { for (int i = 1; i <= n; i++) { for (int j = 0; j < 19; j++) st[i][j] = 0; } } void update(int l, int r, int v) { int k = Log[r-l+1]; st[l][k] = max(st[l][k], v); st[r-(1<<k)+1][k] = max(st[r-(1<<k)+1][k], v); } void gao(int n) { for (int j = 18; j >= 1; j--) { for (int i = 1; i + (1<<j)-1 <= n; i++) { st[i][j-1] = max(st[i][j-1], st[i][j]); st[i+(1<<j-1)][j-1] = max(st[i+(1<<j-1)][j-1], st[i][j]); } } } int main() { int T, n, m; Log[2] = 1; for (int i = 3; i < N; i++) Log[i] = Log[i>>1] + 1; scanf("%d", &T); while(T--) { scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z); init(n); for (int i = 1; i <= m; i++) { for (int j = 1; j <= 3; j++) t[j] = f(); int l = min(t[1]%n + 1, t[2]%n + 1); int r = max(t[1]%n + 1, t[2]%n + 1); int v = t[3] % MOD; update(l, r, v); } gao(n); LL ans = 0; for (int i = 1; i <= n; i++) { int t = st[i][0]; ans ^= (1LL * i * t); } printf("%lld\n", ans); } return 0; }
1008 Hills And Valleys
1009 Innocence
1010 Just So You Know
1011 Kaleidoscope
1012 Lost In The Echo
2018 Multi-University Training Contest 6
1001 oval-and-rectangle
思路:積一下分就能夠了,注意保留6位小數,6位以後直接捨去,不要四捨五入,並且long double不能用printf輸出
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { int T, a, b; scanf("%d", &T); while(T--) { scanf("%d %d", &a, &b); long double ans = (long double)2.0*(long double)a*asin((long double)1.0) + (long double)2.0*(long double)b; LL t = ans * 1000000; printf("%.6f\n", t / (double)1000000.0); } return 0; }
1002 bookshelf
1003 Ringland
1004 Shoot Game
1005 black-and-white
1006 foam-transformation
1007 Variance-MST
1008 Rectangle Outline
1009 Werewolf
思路:首先,咱們不能判斷誰是村民,只能判斷哪些人一定是狼,咱們按相似2-sat的建邊,不過是反向的,用dfs判斷哪些點若是是村民,它必定會產生矛盾
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<int>g[N*2]; vector<int>st; int now, n, vis[N*2]; char s[50]; int dfs(int u, bool f) { if(f) vis[u] = true; for (int i = 0; i < g[u].size(); i++) { if(g[u][i] == now) dfs(g[u][i], true); else dfs(g[u][i], f); } } int main() { int T, x; scanf("%d", &T); while(T--) { scanf("%d", &n); for (int i = 1; i <= 2*n; i++) g[i].clear(), vis[i] = false; st.clear(); for (int i = 1; i <= n; i++) { scanf("%d", &x); scanf("%s", s); if(s[0] == 'v') g[x].pb(i); else g[x+n].pb(i), st.pb(x+n); } int ans = 0; for (int i = 0; i < st.size(); i++) { now = st[i] - n; dfs(st[i], false); } for (int i = 1; i <= n; i++) if(vis[i]) ans++; printf("0 %d\n", ans); } return 0; } /* 10 3 3 v 3 v 2 w 3 2 w 3 v 2 v 4 2 v 3 v 4 v 3 w */
1010 Chopping hands
1011 sacul
1012 Pinball
2018 Multi-University Training Contest 7
1001 Age of Moyu
1002 AraBellaC
1003 YJJ’s Stack
1004 Go to school
1005 GuGuFishtion
思路:容斥
首先,phi(n) = n * ((p1 - 1) / p1) * ((p2 - 1) / p2) * ... * ((pn - 1) / pn) 其中 pi 是n的素因子
其中, phi(1) = 1
對於a和b兩個數,若是它們都有一個公共的素因子p,假設 a 中有p ^ a1,b中有 p^a2
那麼考慮這個素因子的貢獻
phi(a * b) = (p - 1) * p ^ (a1 + a2 - 1) (1)
phi(a) * phi(b) = (p - 1) ^ 2 * p ^ (a1 + a2 - 2) (2)
那麼 (1)/ (2) = p / (p -1)
若是a 和 b 每一個共同的素因子 p, 即a1 和 a2 中有一個是0
那麼 (1)/ (2)= 1,沒有貢獻
那麼只需考慮 gcd(a, b) 的貢獻便可
咱們要求 p1 * p2 * .. * pn / ((p1 - 1) * (p2 - 1) * ... * (pn - 1)) ,其中pi是 gcd(a, b) 的素因子
咱們看一下phi(gcd(a, b))等於什麼
phi(gcd(a, b)) = gcd(a, b) * ((p1 - 1) / p1) * ((p2 - 1) / p2) * ... * ((pn - 1) / pn) 其中 pi 是gcd(a, b)的素因子
因此咱們要求的就等於 (1 / phi(gcd(a, b))) * gcd(a, b) = gcd(a, b) / phi(gcd(a, b)
而後問題就轉換成 1 <= a <= n , 1 <= b <= m 中有多少對gcd(a, b) == k
這個能夠用容斥求:
假設f[d] = d | gcd(a, b) 的個數
假設g[d] = d == gcd(a, b) 的個數
則 g[d] = f[d] - sum(g[i*d], i >= 2)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int N = 1e6 + 5; bool not_pr[N]; int pr[N/5], phi[N], inv[N], f[N]; void get_phi() { phi[1] = 1; int tot = 0; for (int i = 2; i < N; i++) { if(!not_pr[i]) { phi[i] = i-1; pr[tot++] = i; } for (int j = 0; i * pr[j] < N; j++) { not_pr[i*pr[j]] = true; if(i % pr[j] == 0) { phi[i*pr[j]] = phi[i] * pr[j]; break; } else phi[i*pr[j]] = phi[i] * phi[pr[j]]; } } } int main() { get_phi(); int T, n, m, mod; inv[1] = 1; scanf("%d", &T); while(T--) { scanf("%d %d %d", &n, &m, &mod); if(n > m) swap(n, m); for (int i = 2; i <= n; i++) inv[i] = (mod - mod/i) * 1LL * inv[mod%i] % mod; LL ans = 0; for (int i = n; i >= 1; i--) { f[i] = (1LL * (n/i) * (m/i)) % mod; for (int j = i+i; j <= n; j += i) f[i] = (f[i] - f[j] + mod) % mod; ans = (ans + 1LL * f[i] * i % mod * inv[phi[i]] % mod) % mod; } printf("%lld\n", ans); } return 0; }
1006 Lord Li's problem
1007 Reverse Game
1008 Traffic Network in Numazu
1009 Tree
1010 Sequence
思路:咱們發現有連續的一段 p/i 是同樣的,並且p/i的不一樣個數是√p級別的,因而咱們分段進行矩陣快速冪
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int MOD = 1e9 + 7; const int N = 2e5 + 5; int dp[N]; struct Matrix { int a[3][3]; void init() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) a[i][j] = 0; } } void _init() { init(); for (int i = 0; i < 3; i++) a[i][i] = 1; } }A, B; Matrix mul(Matrix a, Matrix b) { Matrix ans; ans.init(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if(a.a[i][j]) { for (int k = 0; k < 3; k++) ans.a[i][k] = (ans.a[i][k] + 1LL * a.a[i][j] * b.a[j][k]) % MOD; } } } return ans; } Matrix q_pow(Matrix a, int k) { Matrix ans; ans._init(); if(k <= 0) return ans; while(k) { if(k&1) ans = mul(ans, a); a = mul(a, a); k >>= 1; } return ans; } int main() { int T, a, b, c, d, p, n; scanf("%d", &T); A.init(); A.a[0][2] = 1; A.a[1][0] = 1; A.a[2][2] = 1; B.init(); while(T--) { scanf("%d %d %d %d %d %d", &a, &b, &c, &d, &p, &n); dp[1] = a; dp[2] = b; if(n <= 50000) { for (int i = 3; i <= n; i++) dp[i] = (1LL * c * dp[i-2] + 1LL * d *dp[i-1] + p/i) % MOD; printf("%d\n", dp[n]); } else { A.a[0][0] = d; A.a[0][1] = c; B.a[0][0] = dp[2]; B.a[1][0] = dp[1]; for (int i = 3; i <= n;) { int j; if(p/i == 0) j = n; else j = min(n, p/(p/i)); B.a[2][0] = p/i; B = mul(q_pow(A, j-i+1), B); i = j+1; } printf("%d\n", B.a[0][0]); } } return 0; }
1011 Swordsman
2018 Multi-University Training Contest 8
1001 Character Encoding
思路:生成函數+廣義二項式定理
隊友代碼:
#include<bits/stdc++.h> using namespace std; const long long mod=998244353; long long POW(long long x,long long n){ long long re=1,base=x; while(n){ if(n&1)(re*=base)%=mod; (base*=base)%=mod; n>>=1; } return re; } long long inv[200010],fac[200010],nfac[200010],ninv[200010]; void getFac(){ fac[0]=1,nfac[0]=1; for(int i=1;i<=200000;i++)fac[i]=fac[i-1]*i%mod; for(int i=1;i<=200000;i++)nfac[i]=(mod+nfac[i-1]*(-i)%mod)%mod; inv[200000]=POW(fac[200000],mod-2); ninv[200000]=POW(nfac[200000],mod-2); for(int i=200000;i>=1;i--)inv[i-1]=inv[i]*i%mod,ninv[i-1]=(mod+ninv[i]*(-i)%mod)%mod; } long long C(long long n,long long m){ if(m<0)return 0; long long re=inv[m]; // re=inv[m]*(n>0?fac[n]:nfac[-n])%mod*(n-m>0?inv[n-m]:ninv[m-n])%mod; if(n>=0&&m>=0)re=re*fac[n]%mod*inv[n-m]%mod; else if(n<0&&m>=0)re=re*ninv[-n-1]%mod*nfac[m-n-1]%mod; // for(int i=0;i<m;i++)re=(re*(n-i)%mod+mod)%mod; // for(int i=1;i<=m;i++)re=(re*(POW(i,mod-2))%mod+mod)%mod; return re; } long long sign(long long x){ if(x&1)return -1; else return 1; } int main(){ int T; getFac(); cin>>T; long long n,m,k; for(int t=1;t<=T;t++){ scanf("%lld%lld%lld",&n,&m,&k); long long ans=0; for(long long i=0;i<=m;i++){ (ans+=C(m,i)*sign(m-i)*C(-m,k-i*n)*sign(-m-k+i*n)%mod+mod)%=mod; } cout<<(ans+mod)%mod<<endl; } return 0; }
1002 Pizza Hub
1003 City Development
1004 Parentheses Matrix
思路:首先,當n和m都是奇數時一個goodness都沒有,隨便構造,其次,當n和m中有一個是偶數時,全部行或者全部列都是構形成匹配的
當n和m都爲偶數時(假設n > m),能夠這樣構造:
咱們發現這樣構造的的goodness是 n + (m - 2) / 2
咱們還能夠這樣構造(犧牲最上面一行和最下面一行以及最左邊一列和最右邊一列來成全中間的全部行和列):
這樣構造的goodness是 n + m - 4
解個不等式: n + (m - 2) / 2 >= n + m - 4
得: m <= 6
綜上所述:
當min(n, m) <= 6 時,採用第一種構造;當min(n, m) > 6時,採用第二種構造
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 222; char s[N][N]; int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); if(n%2 == 0 && m%2 == 0 && min(n, m) > 6) { for (int i = 1; i <= m; i++) s[1][i] = '(', s[n][i] = ')'; for (int i = 2; i < n; i++) { if((i-1)&1) { for(int j = 1; j <= m; j++) { if(j&1) s[i][j] = '('; else s[i][j] = ')'; } } else { s[i][1] = '('; s[i][m] = ')'; for (int j = 2; j < m; j++) { if((j-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar(s[i][j]); } puts(""); } continue; } if(n < m) { if(n%2 == 0) { for (int j = 1; j <= m; j++) { if(j&1) { s[1][j] = '('; s[n][j] = ')'; for (int i = 2; i < n; i++) { if((i-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int i = 1; i <= n; i++) { if(i&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else if(m%2 == 0) { for (int i = 1; i <= n; i++) { if(i&1) { s[i][1] = '('; s[i][m] = ')'; for (int j = 2; j < m; j++) { if((j-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int j = 1; j <= m; j++) { if(j&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) s[i][j] = '('; } } } else { if(m%2 == 0) { for (int i = 1; i <= n; i++) { if(i&1) { s[i][1] = '('; s[i][m] = ')'; for (int j = 2; j < m; j++) { if((j-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int j = 1; j <= m; j++) { if(j&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else if(n%2 == 0) { for (int j = 1; j <= m; j++) { if(j&1) { s[1][j] = '('; s[n][j] = ')'; for (int i = 2; i < n; i++) { if((i-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int i = 1; i <= n; i++) { if(i&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) s[i][j] = '('; } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar(s[i][j]); } puts(""); } } return 0; }
1005 Magic Square
1006 Boolean 3-Array
1007 Card Game
1008 K-Similar Strings
1009 Make ZYB Happy
1010 Taotao Picks Apples
思路:先用二分+st表採用dp求出每一個位置日後的遞增序列長度(對於dp[i],二分找到後面第一個比a[i]大的數a[j],而後dp[i] = dp[j] + 1)
再預處理出原序列到當前位置的遞增序列的值以及長度,而後對於每一個詢問p和q,考慮將a[p]改變成q的影響來求答案
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 10; const int INF = 0x7f7f7f7f; int a[N], dp[N], mx[N][20], v[N], pre[N], Log[N]; void init(int n) { for (int i = 0; i < 19; i++) { for (int j = 1; j + (1<<i) - 1 <= n; j++) { if(i == 0) mx[j][i] = a[j]; else mx[j][i] = max(mx[j][i-1], mx[j+(1<<i-1)][i-1]); } } } int query(int l, int r) { int k = Log[r-l+1]; return max(mx[l][k], mx[r-(1<<k)+1][k]); } int main() { int T, n, M, p, q; scanf("%d", &T); Log[2] = 1; for (int i = 3; i < N; i++) Log[i] = Log[i>>1] + 1; while(T--) { scanf("%d%d", &n, &M); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); a[n+1] = INF; dp[n+1] = 0; init(n); for (int i = n; i >= 1; i--) { int l = i+1, r = n+1, m = l+r >> 1; while(l < r) { if(query(i+1, m) > a[i]) r = m; else l = m+1; m = l+r >> 1; } dp[i] = dp[m] + 1; } v[0] = 0, pre[0] = 0; for (int i = 1; i <= n; i++) { if(a[i] > v[i-1]) { v[i] = a[i]; pre[i] = pre[i-1] + 1; } else v[i] = v[i-1], pre[i] = pre[i-1]; } for (int i = 0; i < M; i++) { scanf("%d %d", &p, &q); int ans = pre[p-1]; if(q > v[p-1]) { ans++; int l = p+1, r = n+1, m = l+r >> 1; while(l < r) { if(query(p+1, m) > q) r = m; else l = m+1; m = l+r >> 1; } ans += dp[m]; } else { int l = p+1, r = n+1, m = l+r >> 1; while(l < r) { if(query(p+1, m) > v[p-1]) r = m; else l = m+1; m = l+r >> 1; } ans += dp[m]; } printf("%d\n", ans); } } return 0; }
1011 Pop the Balloons
1012 From ICPC to ACM
2018 Multi-University Training Contest 9
1001 Rikka with Nash Equilibrium
思路:dp,用滾動數組優化一下空間
從大到小填數字,dp[now][i][j]表示當前填了now個數字,選中了i行和j列的方案數
具體轉移看代碼:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 85; int mod; int dp[2][N][N]; int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d %d", &n, &m, &mod); for (int i = 0; i < 2; i++) { for (int j = 0; j <= n; j++) { for (int k = 0; k <= m; k++) dp[i][j][k] = 0; } } int now = 0; dp[now][1][1] = (n*m) % mod; for (int i = 2; i <= n*m; i++) { for (int j = 1; j <= n; j++) { for (int k = 1; k <= m; k++) { dp[now^1][j][k] = 0; dp[now^1][j][k] = (dp[now^1][j][k] + 1LL * k * (n - j + 1) * dp[now][j-1][k] + 1LL * j * (m - k + 1) * dp[now][j][k-1]) % mod; dp[now^1][j][k] = (dp[now^1][j][k] + (j*k - (i-1)) * 1LL * dp[now][j][k]) % mod; } } now ^= 1; } printf("%lld\n", dp[now][n][m] % mod); } return 0; }
1002 Rikka with Seam
1003 Rikka with APSP
1004 Rikka with Stone-Paper-Scissors
思路:公式 (a' * (c - b) + b' * (a - c) + c' * (b - a)) / (a + b + c)
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll>pii; pii getAns(ll a,ll b,ll c,ll aa,ll bb,ll cc){ ll fi=aa*(c-b)+bb*(a-c)+cc*(b-a); ll se=a+b+c; return pii(fi,se); } int main(){ long long T; cin>>T; long long a,b,c,aa,bb,cc; for(int t=1;t<=T;t++){ cin>>a>>b>>c>>aa>>bb>>cc; pii ans=getAns(a,b,c,aa,bb,cc); ll gcd= __gcd(abs(ans.first),ans.second); if(gcd==ans.second){ cout<<ans.first/gcd<<endl; } else cout<<ans.first/gcd<<'/'<<ans.second/gcd<<endl; } return 0; }
1005 Rikka with Rain
1007 Rikka with Treasure
1010 Rikka with Time Complexity
1011 Rikka with Badminton
思路:
容斥推出公式:2^a * ((b+d+1)* 2^c + 2^b - (b+1))
一個不行的加起來,減去兩個都不行的
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 998244353; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { int T, a, b, c, d;; scanf("%d", &T); while(T--) { scanf("%d %d %d %d", &a, &b, &c, &d); LL ans = q_pow(2, a) * 1LL * ( q_pow(2, c) * 1LL *(b + d + 1) % MOD + q_pow(2, b) - (1+b) + MOD) % MOD; printf("%lld\n", ans); } return 0; }
2018 Multi-University Training Contest 10
1001 Problem A.Alkane
1002 Problem B. Beads
1003 Problem C. Calculate
1005 Problem E. TeaTree
思路:bitset瞎搞
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<int>g[N]; vector<int>f[N]; int v[N], ans[N]; void init() { for (int i = 1; i < N; i++) { for (int j = i; j < N; j += i) { f[j].pb(i); } } } bitset<N> dfs(int u) { bitset<N> res; for (int t : f[v[u]]) res.set(N - t); ans[u] = -1; for (int v : g[u]) { bitset<N> t = dfs(v); ans[u] = max(ans[u], (int)(N - (res&t)._Find_first())); res |= t; } return res; } int main() { int n, u; init(); scanf("%d", &n); for (int i = 2; i <= n; i++) { scanf("%d", &u); g[u].pb(i); } for (int i = 1; i <= n; i++) scanf("%d", &v[i]); dfs(1); for (int i = 1; i <= n; i++) { if(ans[i] <= 0) printf("-1\n"); else printf("%d\n", ans[i]); } return 0; }
1007 Problem G. Cyclic
思路:打表找規律
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=998244353; ll a[100005]; void get_num() { a[1]=1; a[2]=0; a[3]=1; a[4]=1; a[5]=8; a[6]=36; for(ll i=7;i<=100000;i++) { a[i]=(((i-2)*a[i-1])%mod+((i-1)*a[i-2])%mod+((i&1)?1:-1))%mod; } // for(int i=1;i<=20;i++) cout<<a[i]<<endl; } int main() { int t; scanf("%d",&t); get_num(); while(t--) { int n; scanf("%d",&n); // n-=4; cout<<a[n]<<endl; } }
1008 Problem H. Pow
思路:高精度,用pow(2,n)也能夠,跟計算機存儲浮點數存儲方式有關
double指數位能夠從- 2^10 到 2^10 - 1
import java.util.*; import java.lang.*; import java.io.*; import java.math.*; /* Name of the class has to be "Main" only if the class is public. */ public class Main { public static void main (String[] args) { Scanner reader = new Scanner(System.in); int T, n; T = reader.nextInt(); while(T != 0) { T--; n = reader.nextInt(); BigInteger ans = new BigInteger("1"); for (int i = 1; i <= n; i++) { ans = ans.multiply(BigInteger.valueOf(2)); } System.out.println(ans); } // your code goes here } }
1009 Problem I. Count
思路:打表找規律,與歐拉函數有關
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 20000100; int phi[N], prime[N/5]; LL ans[N]; bool not_prime[N]; void Euler() { phi[1]=1; int k=0; for(int i=2;i< N;i++) { if(!not_prime[i]) { phi[i]=i-1; prime[k++]=i; } for(int j=0; i*prime[j] < N; j++) { not_prime[i*prime[j]]=true; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } } int main() { Euler(); ans[0] = 0; for (int i = 1; i < N; i++) { if(i&1) ans[i] = ans[i-1] + phi[i]/2; else ans[i] = ans[i-1] + phi[i]; } int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); printf("%lld\n", ans[n]); } return 0; }
1010 Problem J. CSGO
思路:用二進制枚舉絕對值去掉後每一個數前面的加減號。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 10; const LL INF = 0x3f3f3f3f3f3f3f3f; struct node { int s; int x[5]; }a[N], b[N]; bool cmp1(node a, node b) { return a.s < b.s; } bool cmp2(node a, node b) { return a.x[0] < b.x[0]; } bool cmp3(node a, node b) { return a.x[1] < b.x[1]; } bool cmp4(node a, node b) { return a.x[2] < b.x[2]; } bool cmp5(node a, node b) { return a.x[3] < b.x[3]; } bool cmp6(node a, node b) { return a.x[4] < b.x[4]; } LL mxa[50], mna[50], mxb[50], mnb[50]; int main() { int T; scanf("%d", &T); while(T--) { int n, m, k; scanf("%d %d %d", &n, &m, &k); for (int i = 0; i < (1<<k); i++) mxa[i] = mxb[i] = -INF, mna[i] = mnb[i] = INF; for (int i = 1; i <= n; i++) { scanf("%d", &a[i].s); for (int j = 0; j < k; j++) { scanf("%d", &a[i].x[j]); } for (int j = 0; j < (1<<k); j++) { LL t = a[i].s; for (int l = 0; l < k; l++) { if(j & (1<<l)) t += a[i].x[l]; else t -= a[i].x[l]; } mna[j] = min(mna[j], t); mxa[j] = max(mxa[j], t); } } for (int i = 1; i <= m; i++) { scanf("%d", &b[i].s); for (int j = 0; j < k; j++) { scanf("%d", &b[i].x[j]); } for (int j = 0; j < (1<<k); j++) { LL t = b[i].s; for (int l = 0; l < k; l++) { if(j & (1<<l)) t += b[i].x[l]; else t -= b[i].x[l]; } mnb[j] = min(mnb[j], t); mxb[j] = max(mxb[j], t); } } int up = (1<<k) - 1; LL ans = 0; for (int j = 0; j < (1<<k); j++) { ans = max(ans, mna[j] + mnb[up^j]); ans = max(ans, mna[j] + mxb[up^j]); ans = max(ans, mxa[j] + mnb[up^j]); ans = max(ans, mxa[j] + mxb[up^j]); //cout << j << " " << ans << endl; } printf("%lld\n", ans); } return 0; } /* 100 5 5 1 3 3 -5 0 0 -5 5 0 0 5 2 -4 5 0 0 5 -5 0 0 -5 */
1011 Problem K. Pow2
1012 Problem L.Videos
牛客
思路:找規律
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e3 + 10; const int MOD = 1e9 + 7; LL dp[N][N], t[2*N][2*N]; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { t[1][1] = 3; for (int i = 2; i < 2*N; i++) t[1][i] = (t[1][i-1] + i+1) % MOD; for (int i = 2; i < N; i++) { for (int j = 1; j < N; j++) { if(j == 1) t[i][j] = t[j][i]; else { t[i][j] = (t[i][j-1] * t[1][i+j-1] % MOD * q_pow(t[1][j-1], MOD-2)) % MOD; } } } int n, m; while(~ scanf("%d %d", &n, &m)) { printf("%lld\n", t[n][m]); } return 0; }
思路:狀態壓縮
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 100; pii e1[N], e2[N]; int n, m1, m2, ans; int vis[10][10], cnt[10], vs[10][10], a[10], t[10][10]; map<int, int>mp; int main() { while( ~ scanf("%d %d %d", &n, &m1, &m2)) { mem(vs, 0); mem(cnt, 0); for (int i = 0; i < m1; i++) { scanf("%d %d", &e1[i].fi, &e1[i].se); if(e1[i].fi > e1[i].se) swap(e1[i].fi, e1[i].se); vs[e1[i].fi][e1[i].se] = 1; } mem(vis, 0); for (int i = 0; i < m2; i++) { scanf("%d %d", &e2[i].fi, &e2[i].se); if(e2[i].fi > e2[i].se) swap(e2[i].fi, e2[i].se); vis[e2[i].fi][e2[i].se] = 1; } int sta = 0; for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { sta = sta * 2 + vis[i][j]; } } int ans = 0; mp.clear(); for (int i = 1; i <= n; i++) a[i] = i; do { int s = 0; for (int i = 1; i <= n; i++) { for (int j = i+1; j <= n; j++) { t[i][j] = 0; } } for (int i = 1; i <= n; i++) { for (int j = i+1; j <= n; j++) { if(vs[i][j]) { if(a[i] < a[j]) t[a[i]][a[j]] = 1; else t[a[j]][a[i]] = 1; } } } for (int i = 1; i <= n; i++) { for (int j = i+1; j <= n; j++) { s = s * 2 + t[i][j]; } } mp[s]++; }while(next_permutation(a+1, a+1+n)); for (auto it = mp.begin(); it != mp.end(); it++) { int s = it -> fi; if((s & sta) == s) ans++; } printf("%d\n", ans); } return 0; } /* 3 1 2 1 3 1 2 1 3 4 2 3 1 2 1 3 4 1 4 2 4 3 */
E Removal
思路:莫隊
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; int a[N], cnt[N], blo, ans, res[N]; struct edge { int l, r, bl, id; bool operator < (const edge & t) const { if(bl == t.bl) return r < t.r; else return l < t.l; } }Q[N]; void add(int x) { if(!cnt[a[x]]) ans++; cnt[a[x]]++; } void ded(int x) { cnt[a[x]]--; if(!cnt[a[x]]) ans--; } int main() { int n, q; while( ~scanf("%d %d", &n, &q)) { blo = sqrt(n); mem(cnt, 0); ans = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); if(!cnt[a[i]]) ans++; cnt[a[i]]++; } for (int i = 1; i <= q; i++) { scanf("%d %d", &Q[i].l, &Q[i].r); Q[i].id = i; Q[i].l ++; Q[i].r --; Q[i].bl = (Q[i].l - 1) / blo; } sort(Q+1, Q+1+q); int i = 1, l, r; for (i = 1; i <= q; i++) { if(Q[i].l <= Q[i].r) { l = Q[i].l+1; r = Q[i].l; break; } else res[Q[i].id] = ans; } for (; i <= q; i++) { while(l < Q[i].l) add(l++); while(l > Q[i].l) ded(--l); while(r < Q[i].r) ded(++r); while(r > Q[i].r) add(r--); //cout << l << " " << r << " " << ans << endl; res[Q[i].id] = ans; } for (int i = 1; i <= q; i++) printf("%d\n", res[i]); } return 0; } /* 10 10 1 2 3 4 5 6 7 8 9 10 4 5 5 6 6 7 8 9 4 6 4 7 4 8 4 9 4 10 4 10 */
A run
思路:dp
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 1e9 + 7; LL dp[N][2], sum[N]; int main() { int q, k, l, r; scanf("%d %d", &q, &k); dp[0][0] = 1; for (int i = 1; i < N; i++) { dp[i][0] += dp[i-1][0] + dp[i-1][1]; dp[i][0] %= MOD; if(i - k >= 0) dp[i][1] += dp[i-k][0]; dp[i][1] %= MOD; } sum[0] = 1; for (int i = 1; i < N; i++) { sum[i] = (sum[i-1] + dp[i][0] + dp[i][1]) % MOD; } while(q--) { scanf("%d %d", &l, &r); printf("%lld\n", ((sum[r] - sum[l-1]) % MOD + MOD) % MOD); } return 0; }
B discount
C message
D money
思路:貪心,每次找連續上升的一段
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; int a[N]; int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int pre = 1, cnt = 0, now = 0; LL ans = 0; for (int i = 2; i <= n; i++) { if(a[i] >= a[i-1]) { now = i; } else { if(now > pre && a[now] != a[pre]){ ans += a[now] - a[pre]; cnt += 2; } pre = i; } } if(now > pre && a[now] != a[pre]) ans += a[now] - a[pre], cnt += 2; printf("%lld %d\n", ans, cnt); } return 0; }
E tree
F trade
思路:二分
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 5; LL pren[N], pres[N], sufn[N], sufs[N]; int n; LL T; struct node { int x, a; bool operator < (const node & t) const { return x < t.x; } }a[N]; LL get_pres(int l, int r) { return pres[r] - pres[l] - (a[r].x - a[l].x) * pren[l]; } LL get_sufs(int l, int r) { return sufs[l] - sufs[r] - (a[r].x - a[l].x) * sufn[r]; } bool check(LL m) { int mid = 0, r = 0; LL cnt1 = (m+1)/2; for (int i = 1; i <= n; i++) { while(mid <= n && pren[mid] - pren[i-1] < cnt1) mid++; if(mid > n) break; while(r <= n && pren[r] - pren[i-1] < m) r++; if(r > n) break; if((get_pres(i-1, mid) + get_sufs(mid, r+1) - (pren[r] - pren[i-1] - m) * (a[r].x - a[mid].x)) * 2 <= T) return true; if((get_pres(i-1, mid) + get_sufs(mid, r+1) - (pren[r] - pren[i-1] - m) * (a[i].x - a[mid].x)) * 2 <= T) return true; } // mid = r = n; // for (int i = n; i >= 1; i--) { // while(mid >= 1 && sufn[mid] - sufn[i+1] < cnt1) mid--; // if(mid < 1) break; // while(r >= 1 && sufn[r] - sufn[i+1] < m) r--; // if(r < 1) break; // if((get_pres(r-1, mid) + get_sufs(mid, i+1) - (pren[i] - pren[r-1] - m) * (a[mid].x - a[r].x)) * 2 <= T) return true; // if((get_pres(r-1, mid) + get_sufs(mid, i+1) - (m - pren[i] + pren[r-1]) * (a[i].x - a[mid].x)) * 2 <= T) return true; // } return false; } int main() { scanf("%d %lld", &n, &T); for (int i = 1; i <= n; i++) scanf("%d", &a[i].x); for (int i = 1; i <= n; i++) scanf("%d", &a[i].a); sort(a+1, a+1+n); a[0].x = 0; for (int i = 1; i <= n; i++) { pren[i] = pren[i-1] + a[i].a; pres[i] = pres[i-1] + (a[i].x - a[i-1].x) * pren[i-1]; } a[n+1].x = 1000000000; for (int i = n; i >= 1; i--) { sufn[i] = sufn[i+1] + a[i].a; sufs[i] = sufs[i+1] + (a[i+1].x - a[i].x) * sufn[i+1]; } LL l = 0, r = 1e10, m = (l + r + 1) >> 1; while(l < r) { if(check(m)) l = m; else r = m-1; m = (l + r + 1) >> 1; // cout << l << " " << r << endl; } printf("%lld\n", m); return 0; }
H travel
思路:樹形dp
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 4e5 + 5, M = 5; int a[N]; vector<int>g[N]; LL F[N][5], G[N][5]; void dfs(int o, int u) { LL sum[2][M][M] = {0}, tmp[M][M] = {0}; int now = 0; for (int v : g[u]) { if(v != o) { dfs(u, v); for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { tmp[i][j] = 0; sum[now][i][j] = 0; } } for (int i = 0; i <= 3; i++) { tmp[0][i] = F[v][i]; tmp[1][i] = G[v][i]; } for (int i = 0; i <= 2; i++) { for (int j = 0; i+j <= 2; j++) { for (int k = 0; k <= 3; k++){ for (int l = 0; l+k <= 3; l++) { sum[now][i+j][l+k] = max(sum[now][i+j][l+k], sum[now^1][i][k] + tmp[j][l]); //sum[now][i+j][l+k] = max(sum[now][i+j][l+k], sum[now^1][j][l] + tmp[i][k]); } } } } now ^= 1; } } for (int i = 0; i <= 1; i++) { for (int j = 0; j <= 3; j++) { G[u][j] = max(G[u][j], sum[now^1][i][j] + a[u]); } } for (int i = 0; i <= 2; i++) { for (int j = 1; j <= 3; j++) { F[u][j] = max(F[u][j], sum[now^1][i][j-1] + a[u]); } } for (int i = 0; i <= 3; i ++) F[u][i] = max(F[u][i], sum[now^1][0][i]); } int main() { int n, u, v; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i < n; i++) { scanf("%d %d", &u, &v); g[v].pb(u); g[u].pb(v); } dfs(0, 1); printf("%lld\n", F[1][3]); return 0; }
I car
思路:風車狀
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; bool r[N], c[N]; int main() { int n, m, x, y; scanf("%d %d", &n, &m); for (int i = 0; i < m; i++) { scanf("%d %d", &x, &y); r[x] = true; c[y] = true; } int ans = 0; if(n % 2) { for (int i = 1; i <= n; i++) { if(i == n/2 + 1) continue; if(!r[i]) ans++; } for (int i = 1; i <= n; i++) { if(i == n/2 + 1) continue; if(!c[i]) ans++; } if(!r[n/2 + 1] || !c[n/2 + 1]) ans++; } else { for (int i = 1; i <= n; i++) if(!r[i]) ans++; for (int i = 1; i <= n; i++) if(!c[i]) ans++; } printf("%d\n", ans); return 0; }
J farm
思路:隨機或者樹狀數組
隨機
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 1e9 + 5; vector<int>a[N]; vector<LL> s1[N], s2[N]; int b1[N], b2[N]; void add(int x, int y, int k) { s1[x][y] += b1[k]; s2[x][y] += b2[k]; } void del(int x, int y, int k) { s1[x][y] -= b1[k]; s2[x][y] -= b2[k]; } void cal(int x, int y) { s1[x][y] += s1[x-1][y] + s1[x][y-1] - s1[x-1][y-1]; s2[x][y] += s2[x-1][y] + s2[x][y-1] - s2[x-1][y-1]; } int main() { srand(time(NULL)); int n, m, T, x1, y1, x2, y2, k; scanf("%d %d %d", &n, &m, &T); for (int i = 0; i <= n+2; i++) a[i].resize(m+3), s1[i].resize(m+3), s2[i].resize(m+3); for (int i = 1; i < N; i++) { b1[i] = (random() % MOD) + N; b2[i] = (random() % MOD) + N/2; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]); } while(T--) { scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &k); add(x1, y1, k); del(x1, y2+1, k); del(x2+1, y1, k); add(x2+1, y2+1, k); } int ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cal(i, j); if(s1[i][j] % b1[a[i][j]] == 0 && s2[i][j] % b2[a[i][j]] == 0) ans++; } } printf("%d\n", n*m - ans); return 0; }
樹狀數組
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 1e9 + 5; vector<int> bit[N], id[N], t[N]; vector<bool>vis[N]; vector<pii>pos[N]; int n, m; struct query { int x1, x2, y1, y2; }Q[N]; void add(int x, int y, int t) { for (int i = x; i <= n; i += i&-i) { for (int j = y; j <= m; j += j&-j) { bit[i][j] += t; } } } int sum(int x, int y) { int ans = 0; for (int i = x; i; i -= i&-i) { for (int j = y; j; j -= j&-j) { ans += bit[i][j]; } } return ans; } int main() { int T, k, mx = 0, a; scanf("%d %d %d", &n, &m, &T); for (int i = 0; i <= n+2; i++) bit[i].resize(m+3), vis[i].resize(m+3), t[i].resize(m+3); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &a); pos[a].push_back({i, j}); mx = max(mx, a); } } for (int i = 0; i < T; i++) { scanf("%d %d %d %d %d", &Q[i].x1, &Q[i].y1, &Q[i].x2, &Q[i].y2, &k); id[k].push_back(i); mx = max(mx, k); } for (int i = 1; i <= mx; i++) { for (int j = 0; j < pos[i].size(); j++) { if(sum(pos[i][j].fi, pos[i][j].se) != 0) vis[pos[i][j].fi][pos[i][j].se] = true; } for (int j = 0; j < id[i].size(); j++) { add(Q[id[i][j]].x1, Q[id[i][j]].y1, 1); add(Q[id[i][j]].x1, Q[id[i][j]].y2 + 1, -1); add(Q[id[i][j]].x2 + 1, Q[id[i][j]].y1, -1); add(Q[id[i][j]].x2 + 1, Q[id[i][j]].y2 + 1, 1); } for (int j = 0; j < pos[i].size(); j++) { if(!vis[pos[i][j].fi][pos[i][j].se]) { t[pos[i][j].fi][pos[i][j].se] = sum(pos[i][j].fi, pos[i][j].se); } } } int ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if(!vis[i][j]) { if(t[i][j] != sum(i, j)) ans++; } else ans++; } } printf("%d\n", ans); return 0; }
K carpet
思路:hash+KMP找最小循環節,而後用二維單調隊列求區間最小
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 1e9 + 7; const int INF = 0x7f7f7f7f; string s[N]; vector<int>cost[N], mx[N]; int row[N], col[N], nxt[N]; int get_loop(int a[], int n) { nxt[0] = -1; for (int i = 1; i < n; i++) { int j = nxt[i-1]; while(a[j+1] != a[i] && j >= 0) j = nxt[j]; if(a[j+1] == a[i]) nxt[i] = j+1; else nxt[i] = -1; } return n - (nxt[n-1]+1); } int main() { fio; int n, m; cin >> n >> m; for (int i = 0; i < n; i++) cin >> s[i]; for (int i = 0; i < n; i++) cost[i].resize(m+2), mx[i].resize(m+2); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) cin >> cost[i][j]; } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { row[i] = (233LL * row[i] + s[i][j]) % MOD; col[j] = (233LL * col[j] + s[i][j]) % MOD; } } int a = get_loop(col, m), b = get_loop(row, n); deque<int>q; for (int i = 0; i < n; i++) { q.clear(); for (int j = 0; j < m; j++) { while(!q.empty() && cost[i][q.back()] <= cost[i][j]) q.pop_back(); q.push_back(j); while(!q.empty() && q.front() < j - a + 1) q.pop_front(); mx[i][j] = cost[i][q.front()]; } } int ans = INF; for (int j = a-1; j < m; j++) { q.clear(); for (int i = 0; i < n; i++) { while(!q.empty() && mx[q.back()][j] <= mx[i][j]) q.pop_back(); q.push_back(i); while(!q.empty() && q.front() < i - b + 1) q.pop_front(); if(i >= b-1) { ans = min(ans, mx[q.front()][j]); } } } cout << 1LL * ans * (a+1) * (b+1) << endl; return 0; }
思路:揹包,用short類型開數組
#pragma GCC optimize(2) #include<bits/stdc++.h> #define fi first.first.first #define se first.first.second #define th first.second #define fo second using namespace std; const int maxn=40; int p[maxn],a[maxn],c[maxn],m[maxn],g[maxn]; short dp[38][38][38][38][38]; bool cat[38][38][38][38][38]; vector<int> ans; int main(){ int n; int P,A,C,M; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d%d%d",p+i,a+i,c+i,m+i,g+i); scanf("%d%d%d%d",&P,&A,&C,&M); int i,j,k,l,q; for(i=1;i<=n;i++) for(j=0;j<=P;j++) for(k=0;k<=A;k++) for(l=0;l<=C;l++) for(q=0;q<=M;q++){ if(j>=p[i]&&k>=a[i]&&l>=c[i]&&q>=m[i]){ cat[i][j][k][l][q]=1; dp[i][j][k][l][q]=dp[i-1][j-p[i]][k-a[i]][l-c[i]][q-m[i]]+g[i]; } if(dp[i-1][j][k][l][q]>=dp[i][j][k][l][q])dp[i][j][k][l][q]=dp[i-1][j][k][l][q],cat[i][j][k][l][q]=0; } short ansp,ansa,ansc,ansm; int maxans=0; for(int j=0;j<=P;j++) for(int k=0;k<=A;k++) for(int l=0;l<=C;l++) for(int q=0;q<=M;q++) if(dp[n][j][k][l][q]>maxans)ansp=j,ansa=k,ansc=l,ansm=q,maxans=dp[n][j][k][l][q]; if(maxans==0)return cout<<0,0; for(int i=n;i>=1;i--){ if(cat[i][ansp][ansa][ansc][ansm]){ ans.push_back(i); ansp-=p[i],ansa-=a[i],ansc-=c[i],ansm-=m[i]; } } cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++)cout<<ans[i]-1<<' '; return 0; }
思路:splay實現區間反轉
#include<bits/stdc++.h> #define MAXN 100005 using namespace std; int read(){ char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x; } int n,m,root; struct Splay{ int fa[MAXN],son[MAXN][2],siz[MAXN],add[MAXN]; void up(int k){ siz[k]=siz[son[k][0]]+siz[son[k][1]]+1; } void down(int k){ if(add[k]){ swap(son[k][0],son[k][1]); add[son[k][0]]^=1;add[son[k][1]]^=1; add[k]=0; } } void rotate(int x,int &k){ int f=fa[x],gran=fa[f],opt; opt=(son[f][1]==x); if(f==k) k=x;else son[gran][son[gran][1]==f]=x; son[f][opt]=son[x][opt^1];fa[son[f][opt]]=f; son[x][opt^1]=f;fa[f]=x;fa[x]=gran; siz[x]=siz[f];up(f); } void splay(int x,int &k){ while(x!=k){ int f=fa[x],gran=fa[f]; if(f!=k) rotate((son[f][0]==x)^(son[gran][0]==f)?x:f,k); rotate(x,k); } } void build(int l,int r,int f){ if(l>r) return; int mid=(l+r)>>1;if(mid<f) son[f][0]=mid;else son[f][1]=mid; fa[mid]=f;siz[mid]=1; if(l==r) return; build(l,mid-1,mid);build(mid+1,r,mid); up(mid); } int find(int x,int k){ down(x);int s=siz[son[x][0]]; if(s+1==k) return x; if(k<=s) return find(son[x][0],k); else return find(son[x][1],k-s-1); } void revers(int l,int r){ int x=find(root,l),y=find(root,r+2); splay(x,root);splay(y,son[root][1]); int pl=son[y][0];add[pl]^=1; } }T; int main() { n=read();m=read(); root=(n+3)>>1;T.build(1,n+2,root); for(int i=1;i<=m;i++){ int l=read(),r=read(); r=l+r-1; T.revers(1,l-1); T.revers(l,r); T.revers(1,r); } for(int i=2;i<=n+1;i++) printf("%d ",T.find(root,i)-1); return 0; }
思路:字符串hash+排序
代碼:
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; typedef unsigned long long ULL; typedef pair<ULL,ULL> pll; typedef pair<int,int> pii; const int maxn=1000010; const int base=233; char s[maxn]; ULL POW[maxn]; pll Hash[maxn]; pii p[maxn]; vector<int> vec[maxn]; int main(){ scanf("%s",s); int n=strlen(s); ULL now=0; POW[0]=1; for(int i=1;i<=n;++i)POW[i]=POW[i-1]*base; for(int i=0;i<n;++i)now=now*base+(s[i]-'a'+1); for(int i=0;i<n;i++){ Hash[i]={now,(ULL)i}; now=now-(s[i]-'a'+1)*POW[n-1]; now=now*base+(s[i]-'a'+1); } sort(Hash,Hash+n); int anscnt=0; for(int i=0;i<n;i++){ if(!i||Hash[i-1].first!=Hash[i].first)++anscnt,p[anscnt]={Hash[i].second,anscnt}; vec[anscnt].emplace_back(Hash[i].second); } sort(p+1,p+1+anscnt); printf("%d\n",anscnt); for(int i=1;i<=anscnt;i++){ printf("%d ",vec[p[i].second].size()); for(auto w:vec[p[i].second]){ printf("%d ",w); } puts(""); } return 0; }
思路:枚舉小於n的素數,每一個素數和比它小的素數匹配,最後答案乘2
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e7 + 5; bool vis[N]; vector<int>p; void seive() { for (int i = 2; i < N; i++) { if(!vis[i]) { p.push_back(i); for (int j = i+i; j < N; j += i) vis[j] = true; } } } int main() { seive(); int n; scanf("%d", &n); LL ans = 0; for (int i = 0; i < p.size(); i++) { if(p[i] > n) break; ans += n/p[i] * 1LL * i; } ans *= 2; printf("%lld\n", ans); return 0; }
I Expected Size of Random Convex Hull
思路:構造,花了幾個小時想了一個超複雜的構造TAT,看看別人的構造,感受本身蠢哭了
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 555; int a[N][N]; map<int, int>mp; bool check(int n) { mp.clear(); for (int i = 1; i <= n; i++) { int s = 0; for (int j = 1; j <= n; j++) { s += a[i][j]; } mp[s]++; } for (int i = 1; i <= n; i++) { int s = 0; for (int j = 1; j <= n; j++) { s += a[j][i]; } mp[s]++; } if(mp.size() == n*2) return true; else return false; } int main() { fio; int T, n; cin >> T; while(T--) { cin >> n; if(n&1) { cout << "impossible" << endl; continue; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) a[i][j] = -1; } for (int i = 1; i <= n/2; i++) { for (int j = 1; j <= n/2; j++) { a[i][j] = 1; a[i+n/2][j+n/2] = -1; if(i + j > n/2 + 1) a[i][j+n/2] = 0; else a[i][j+n/2] = 1; } } int tot = n/2, cnt, res; if(tot&1) cnt = tot/2+1; else cnt = tot/2; res = tot - cnt; for (int i = 1; i <= cnt; i++) { for (int j = 1; j <= cnt; j++) { if(i + j > cnt + ((tot+1)%2)) a[i+tot][j] = 0; else a[i+tot][j] = 1; } } for (int i = 1; i <= res; i++) { for (int j = 1; j <= res; j++) { if(i + j > res) a[i+tot+cnt][j+cnt] = 0; else a[i+tot+cnt][j+cnt] = -1; } } cout << "possible" << endl; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << a[i][j] << " "; cout << endl; } } return 0; }
E Skyline
思路:模擬
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef long long LL; char s[2005][2005]; bool check(char a,char b, char c,char d) { if(a==b&&a==c&&a==d) return true; return false; } int main() { int t; while(scanf("%d",&t)!=EOF) { while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%s",s[i]); int Maxc=INT_MAX; int Maxr=INT_MAX; for(int i=0;i<n;i++) { int cnt=0; for(int j=0;j<m/2;j++) { if(s[i][j]==s[i][m-j-1]) cnt++; else { cnt++; break; } } Maxr=min(Maxr,cnt); } for(int i=0;i<m;i++) { int cnt=0; for(int j=0;j<n/2;j++) { if(s[j][i]==s[n-j-1][i]) cnt++; else { cnt++; break; } } Maxc=min(Maxc,cnt); } Maxc--; Maxr--; printf("%d\n",Maxc*Maxr); } } }
思路:統計一下出現次數爲i的數的個數,而後從小到大枚舉數a[i],檢查一下將全部出現次數大於等於a[i]出現次數的數刪掉成都小於a[i]的個數,可行就更新答案。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5 ; int a[N]; int t[N]; LL sum[N]; int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i <= n; i++) t[i] = 0; sort(a, a+n); int now = 1; for (int i = 1; i < n; i++) { if(a[i] != a[i-1]) { t[1]++; t[now+1]--; now = 1; } else now++; } t[1]++; t[now+1]--; now = 1; for (int i = 1; i <= n; i++) t[i] += t[i-1]; for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + t[i]; int ans = -1; for (int i = 1; i < n;i++) { if(a[i] != a[i-1]) { if(t[now] - 1 + sum[n] - sum[now] <= m) ans = a[i-1]; now = 1; } else now++; } if(t[now] - 1 + sum[n] - sum[now] <= m) ans = a[n-1]; printf("%d\n", ans); } return 0; }
A gpa
思路:01分數規劃
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const double eps = 1e-7; int n, k; pii a[N]; double t[N]; bool check(double m) { for (int i = 0; i < n; i++) t[i] = (double)a[i].fi*a[i].se - m*a[i].fi; sort(t, t+n); double tt = 0; for (int i = k; i < n; i++) tt += t[i]; //cout<< fixed << setprecision(6)<< tt << endl; return tt >= 0; } int main() { scanf("%d %d", &n, &k); for (int i = 0; i < n; i++) scanf("%d", &a[i].fi); for (int i = 0; i < n; i++) scanf("%d", &a[i].se); double l = 0, r = 1e4 + 5, m = (l+r)/2; while(l + eps< r) { if(check(m)) l = m; else r = m; m = (l+r) / 2; } printf("%.10f\n", m); return 0; }
B div
C grf
D inv
E room
F take
思路:考慮每一個位置對答案的貢獻,但前位置被替換當且僅當前面全部比當前小的都沒有被替換(即以前比當前小的盒子的鑽石都沒有鑽石,有1-pj的機率),這個用樹狀數組維護個前綴積就能夠了
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 998244353; pii a[N]; LL bit[N]; int n; vector<int>vc; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } void add(int x, LL y) { while(x <= n) bit[x] *= y, bit[x] %= MOD, x += x&-x; } LL sum(int x) { LL ans = 1; while(x) ans *= bit[x], ans %= MOD, x -= x&-x; return ans; } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d %d", &a[i].fi, &a[i].se), vc.pb(a[i].se); sort(vc.begin(), vc.end()); vc.erase(unique(vc.begin(), vc.end()), vc.end()); for (int i = 0; i < n; i++) a[i].fi = (1LL * a[i].fi * q_pow(100, MOD-2)) % MOD, a[i].se = lower_bound(vc.begin(), vc.end(), a[i].se) - vc.begin(), a[i].se = n - a[i].se; for (int i = 0; i <= n; i++) bit[i] = 1; LL ans = 0; for (int i = 0; i < n; i++) { ans = (ans + a[i].fi * sum(a[i].se - 1)) % MOD; add(a[i].se, (1 - a[i].fi) % MOD); } ans = (ans + MOD) % MOD; printf("%lld\n", ans); return 0; }
G max
思路:找第一個i和n互質,質數之間距離很短
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { fio; int c, n; cin >> c >> n; n /= c; for (int i = n; i >= 1; i--) { if(__gcd(i, n) == 1) { cout << 1LL * n * i * c * c << endl; return 0; } } cout << -1 << endl; return 0; }
H subseq
I vcd
思路:首先,一個點的集合確定能夠,其次,二個點若是想知足題意,那麼y要求不一樣,三點的集合若是想知足題意,那麼要三個點構成「<」形狀,最後,超過三個點的集合都不能夠。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 998244353; pii a[N]; vector<int>vc; int n, t[N], bit[N]; void add(int x) { while(x <= n) bit[x]++, x += x&-x; } int sum(int x) { int ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } bool cmp(pii a, pii b) { return a.fi > b.fi; } LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d %d", &a[i].fi, &a[i].se), vc.pb(a[i].se); sort(vc.begin(), vc.end()); vc.erase(unique(vc.begin(), vc.end()), vc.end()); for (int i = 1; i <= n; i++) a[i].se = lower_bound(vc.begin(), vc.end(), a[i].se) - vc.begin() + 1, t[a[i].se]++; sort(a+1, a+1+n, cmp); LL ans = 0; for (int i = 1; i <= n; i++) ans += 1LL*t[i]*(n-t[i]), ans %= MOD; ans = (ans * q_pow(2, MOD-2)) % MOD; ans = (ans + n) % MOD; int pos = 1; for (int i = 1; i <= n; i++) { if(a[i].fi != a[i-1].fi) { while(pos < i) { add(a[pos++].se); } } int up = sum(n) - sum(a[i].se); int down = sum(a[i].se - 1); ans += 1LL * up * down; ans %= MOD; } printf("%lld\n", ans); return 0; }
J plan
思路:答案確定是某一種房間選了不少,咱們暴力房間少的那一個,3個就夠了
思路:模擬+貪心,每次歌手都唱大於對方最大值的歌
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e4 + 5; set<int>s[N]; int mx[N]; bool vis[N]; int main() { int T, n, t; scanf("%d", &T); for (int cs = 1; cs <= T; cs++) { scanf("%d", &n); mem(mx, 0); for (int i = 1; i <= (1<<n); i++) { s[i].clear(); for (int j = 1; j <= n; j++) { scanf("%d", &t); s[i].insert(t); mx[i] = max(mx[i], t); } } mem(vis, false); for (int i = 1; i <= n; i++) { int last = -1; for (int j = 1; j <= (1<<n); j++) { if(!vis[j]) { if(last == -1) last = j; else { int mm = mx[last], mmm = mx[j]; if(mm > mmm) { vis[j] = true; auto it = s[last].lower_bound(mmm); s[last].erase(it); mx[last] = 0; for (auto t : s[last]) mx[last] = max(mx[last], t); } else { vis[last] = true; auto it = s[j].lower_bound(mm); s[j].erase(it); mx[j] = 0; for (auto t : s[j]) mx[j] = max(mx[j], t); } last = -1; } } } } for (int i = 1; i <= (1<<n); i++) if(!vis[i]) { printf("Case #%d: %d\n", cs, i); break; } } return 0; }
思路:考慮第i次操做i ~ n的全部集合都加相同的數,因此咱們只考慮每一個數第一次出如今哪裏,由於若是這個數在後面有沒有出現過是沒有關係的,後面的全部集合都有這個數
考慮總共出現了k個數,第一個位置確定出現了一個數,因此從n-1個位置中選k-1個位置,再加上第一個位置構成k個位置,做爲這k個數第一次出現的位置,總共有C(n-1, k-1)中
而後考慮這k個數有多少種可能,有A(m, k)可能,因此對於出現k個數,有C(n-1, k-1) * A(m, k)中可能,而後將k從1枚舉min(n, m)求個和就能夠了
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 998244353; int inv[N]; void init() { inv[1] = 1; for (int i = 2; i < N; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD; } int main() { init(); int T; LL n, m; scanf("%d", &T); for (int cs = 1; cs <= T; cs++) { scanf("%lld %lld", &n, &m); int up = min(n, m); LL ans = 0, C = 1, A = m%MOD; for (int i = 1; i <= up; i++) { ans = (ans + C * A) % MOD; n--; m--; C = ((C * n) % MOD * inv[i]) % MOD; A = (A * m) % MOD; } printf("Case #%d: %lld\n", cs, ans); } return 0; }
思路:發現每一個身體只能連一個頭,因此對於每一個身體選一個最大的權值,它連哪一個頭都無所謂,這樣是最優的
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; int mx[N]; int main() { int T, a, b, c, n, m, k; scanf("%d", &T); for (int cs = 1; cs <= T; cs++) { scanf("%d %d %d", &n, &m, &k); for (int i = 1; i <= n; i++) mx[i] = 0; for (int i = 0; i < k; i++) { scanf("%d %d %d", &a, &b, &c); mx[b] = max(c, mx[b]); } LL ans = 0; for (int i = 1; i <= m; i++) ans += mx[i]; printf("Case #%d: %lld\n", cs, ans); } return 0; }
F Squirtle
G Pikachu
H Eevee
思路:因爲數據隨機,因此最大的幾個數有很大可能互質,因此挑出最大的幾個數兩兩求lcm取最大,能夠用stl裏面的nth_element(),很強大
若是用set的話,注意保存一下當前set的最小值,與最小值判斷一下需不須要加進set,不然的化常數太大會超時
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; typedef long long ll; unsigned int A,B,C; unsigned int x=A,y=B,z=C; inline unsigned int tang() { unsigned int t; x^=x<<16; x^=x>>5; x^=x<<1; t=x; x=y; y=z; z=t^x^y; return z; } unsigned int num[10000005]; set<unsigned int>mx; inline unsigned long long gcd(unsigned long long a, unsigned long long b) { return b ? gcd(b, a%b): a; } inline unsigned long long lcm(unsigned long long x,unsigned long long y) { return x/__gcd(x,y)*y; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin>>t; for(int tt=1;tt<=t;tt++) { int n; cin>>n>>A>>B>>C; x=A,y=B,z=C; mx.clear(); unsigned int mn; for(int i=1;i<=n;i++) { num[i]=tang(); if(mx.size() < 20) mx.insert(num[i]), mn = *mx.begin(); else { if(num[i] > mn) { mx.insert(num[i]); mx.erase(mx.begin()); mn = *mx.begin(); } } } unsigned long long Max=0; vector<unsigned int>vc; for (auto x:mx) vc.push_back(x); for (int i = 0; i < vc.size(); i++) { for (int j = i+1; j < vc.size(); j++) { Max = max(Max, lcm(vc[i], vc[j])); } } cout<<"Case #"<<tt<<": "<<Max<<endl; } return 0; }
A Minimum Cost Perfect Matching
思路:對於每一個i找比i小的~i,將兩個鏈接起來,這樣最小花費是0
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 5; bool vis[N]; int a[N]; int main() { int n; scanf("%d", &n); for (int i = n - 1; i >= 0; i--) { int t = 0; bool f = false; for (int j = 29; j >= 0; j--) { if((i & (1 << j)) == 0) { if(f) t = t*2 + 1; } else { f = true; t = t*2; } } if(!vis[i] && !vis[t]) { a[i] = t; a[t] = i; vis[t] = true; vis[i] = true; } } for (int i = 0; i < n; i++) printf("%d%c", a[i], " \n"[i==n]); return 0; }
思路:搜索優化,預處理出最後三步的結果
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb emplace_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int N = (1<<16) + 10, M = (1<<20) + 10; bool t[20][M]; char s[M]; int dp[5][N], ans = 0; void init(int n) { int up = 1; for (int i = 0; i < n; i++) up = up * 3; for (int i = 0; i < (1<<(1<<n)); i++) { for (int j = 0; j < (1<<n); j++) { if(i & (1<<j)) t[n][j] = 1; else t[n][j] = 0; } for (int j = 0; j < up; j++) { int tmp = j; for (int k = n-1; k >= 0; k--) { for (int l = 0; l < (1<<k); l++) { if(tmp%3 == 0) t[k][l] = t[k+1][l*2]^t[k+1][l*2+1]; else if(tmp%3 == 1) t[k][l] = t[k+1][l*2]&t[k+1][l*2+1]; else t[k][l] = t[k+1][l*2]|t[k+1][l*2+1]; } tmp /= 3; } dp[n][i] += t[0][0]; } } } void dfs(int n) { for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]^t[n+1][i*2+1]; if(n == 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i]; ans += dp[n][st]; } else dfs(n-1); for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]&t[n+1][i*2+1]; if(n == 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i]; ans += dp[n][st]; } else dfs(n-1); for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]|t[n+1][i*2+1]; if(n == 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i]; ans += dp[n][st]; return ; } else dfs(n-1); } int main() { int n; scanf("%d", &n); scanf("%s", s); init(min(n, 3)); if(n <= 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + (s[i] == '1'); printf("%d\n", dp[n][st]); } else { for (int i = 0; i < (1<<n); i++) t[n][i] = s[i] == '1'; dfs(n-1); printf("%d\n", ans); } return 0; }
思路:打表能夠發現當k很大時能夠由t個點的徹底圖加上另外5個點與t個點中的部分點相連構成k個4元組,即存在t, a, b, c, d, e,
使得C(t, 4) + C(a, 3) + C(b, 3) + C(c, 3) + C(d, 3)+ C(e, 3) == k
預處理C(e, 3), 暴力枚舉a,b, c, d
或者預處理C(d, 3) + C(e, 3) , 暴力枚舉a,b, c
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int C4[100], C3[100], t; int C(int n, int m) { int ans = 1; if(n < m) return 0; for (int i = n; i >= n-m+1; i--) ans *= i; for (int i = 1; i <= m; i++) ans /= i; return ans; } void solve(int a, int b, int c, int d, int e) { printf("%d %d\n", t+5, C(t, 2) + a + b + c + d + e); for (int i = 1; i <= t; i++) { for (int j = i+1; j <= t; j++) printf("%d %d\n", i, j); } for (int i = 1; i <= a; i++) printf("%d %d\n", i, t+1); for (int i = 1; i <= b; i++) printf("%d %d\n", i, t+2); for (int i = 1; i <= c; i++) printf("%d %d\n", i, t+3); for (int i = 1; i <= d; i++) printf("%d %d\n", i, t+4); for (int i = 1; i <= e; i++) printf("%d %d\n", i, t+5); } map<int, pii>mp; int main() { int k; scanf("%d", &k); t = 4; for (int i = 3; i <= 80; i++) C4[i] = C(i, 4), C3[i] = C(i, 3); while(C4[t+1] <= k) t++; t = min(t, 70); for (int i = 2; i <= t; i++) { for (int j = 2; j <= t; j++) { mp[C3[i] + C3[j]] = {i, j}; } } for (int i = 2; i <= t; i++) { for (int j = i; j <= t; j++) { for (int l = j; l <= t; l++) { if(mp.find(k - C4[t] - C3[i] - C3[j] - C3[l]) != mp.end()) { solve(i, j, l, mp[k - C4[t] - C3[i] - C3[j] - C3[l]].fi, mp[k - C4[t] - C3[i] - C3[j] - C3[l]].se); return 0; } } } } return 0; }
G Rock-Paper-Scissors Tournament
思路:O(n*m)處理每一個點往右能到哪裏,往下能到哪裏,而後O(52*n*m)對於每一個點往右掃列最小,而後往下求行最小
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int N = 1e3 + 5; char s[N][N]; int a[N][N], r[N][N], d[N][N], mn[N][N]; int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%s", s[i]+1); for (int j = 1; j <= m; j++) if(isupper(s[i][j])) a[i][j] = s[i][j] - 'A' + 26; else a[i][j] = s[i][j] - 'a'; } for (int i = 1; i <= n; i++) { LL st = 0; int pre = 1; for (int j = 1; j <= m; j++) { if(j > 1) st ^= 1LL << a[i][j-1]; r[i][j] = m; bool f = true; for (int k = pre; k <= m; k++) { if(st & (1LL << a[i][k])) { f = false; r[i][j] = k-1; pre = k; break; } st |= 1LL << a[i][k]; } if(f) pre = m+1; } } for (int j = 1; j <= m; j++) { LL st = 0; int pre = 1; for (int i = 1; i <= n; i++) { if(i > 1) st ^= 1LL << a[i-1][j]; d[i][j] = n; bool f = true; for (int k = pre; k <= n; k++) { if(st & (1LL << a[k][j])) { f = false; d[i][j] = k-1; pre = k; break; } st |= 1LL << a[k][j]; } if(f) pre = n+1; } } LL ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { mn[i][j] = d[i][j]; for (int k = j+1; k <= r[i][j]; k++) { mn[i][k] = min(mn[i][k-1], d[i][k]); } int now = r[i][j]; for (int k = i; k <= d[i][j]; k++) { now = min(now, r[k][j]); while(mn[i][now] < k && now >= j) now --; if(now < j) break; ans += now - j + 1; } } } printf("%lld\n", ans); return 0; }
oeis公式
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int MOD = 998244353; const int N = 3e5 + 5; LL C[N], NN[N], inv[N], p[N], ans = 0; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } void init(int n) { n--; inv[1] = 1; for (int i = 2; i <= n; i++) inv[i] = (MOD - MOD/i) * inv[MOD%i] % MOD; p[0] = 1; for (int i = 1; i <= n; i++) p[i] = (p[i-1] * 2) % MOD; C[0] = 1; for (int i = 1; i <= n; i++) C[i] = ((C[i-1] * (n-i+1)) % MOD * inv[i]) % MOD; for (int i = 1; i <= n; i++) NN[i] = (C[i] * C[i-1]) % MOD * inv[n] % MOD; for (int i = 1; i <= n; i++) ans = (ans + NN[i] * p[n-i+1]) % MOD; } int main() { int n; scanf("%d", &n); if(n == 1) return 0*puts("1"); init(n); printf("%lld\n", ans); return 0; }
思路:立體幾何歐拉公式:V - E + F = 2 (V:頂點個數, E:邊條數, F:面個數,怎麼記憶呢,維數爲0的點加上維數爲2的面減去維數爲1的線等於2)
F = E - V + 2
首先,將平面圖當作立體圖(以正多邊形爲底的立體圖),那麼問題就轉換成已知點個數和邊條數來求多面體的面有多少個
內部交點個數(從n個點中選4個頂點連起來):C(n, 4)
因此定點個數:C(n, 4) + n
每一個內部交點會多產生兩條邊,因此邊個數: C(n, 2) + C(n, 4) * 2
因此F = E - V + 2 = (C(n, 2) + C(n, 4) * 2) - (C(n, 4) + n) + 2 = C(n, 2) + C(n, 4) - n + 2
減去底面因此要減一
答案爲C(n, 2) + C(n, 4) - n + 1
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int MOD = 1e9 + 7; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } LL C(int n, int m) { LL ans = 1; for (int i = n; i >= n-m+1; i--) ans = (ans * i) % MOD; for (int i = 1; i <= m; i++) ans = (ans * q_pow(i, MOD-2)) % MOD; return ans; } int main() { int n; cin >> n; LL ans = (C(n, 4) + C(n, 2) - n + 1 + MOD) % MOD; cout << ans << endl; return 0; }
思路:FWT
隊友代碼:
#include<bits/stdc++.h> using namespace std; #define int long long int n,a[530000],b[530000],tot,x,ha=1e9+7,inv2; int qpow(int a,int b) { int ans=1; while(b){if(b&1)ans=ans*a%ha;a=a*a%ha,b>>=1;} return ans; } void fwt(int *a,int n,int t) { for(int i=1;i<n;i<<=1) { for(int j=0;j<n;j+=(i<<1)) for(int k=j;k<i+j;k++) { int x=a[k],y=a[k+i]; a[k]=(x+y)%ha,a[k+i]=(x-y+ha)%ha; if(t)a[k]=a[k]*inv2%ha,a[k+i]=a[k+i]*inv2%ha; } } } signed main() { scanf("%lld",&n); inv2=qpow(2,ha-2); for(int i=0;i<n;i++)scanf("%lld",&a[i]); for(int i=0;i<n;i++)scanf("%lld",&b[i]); fwt(a,n,0);fwt(b,n,0); for(int i=0;i<n;i++)b[i]=b[i]*qpow(a[i],ha-2)%ha; fwt(b,n,1); for(int i=0;i<n;i++)printf("%lld\n",b[i]); return 0; }
B Enumeration not optimization
C Gambling
思路:dp
狀態定義:dp[i][0]表示到第i位以0結尾的指望分數,dp[i][1]表示到第i位以1結尾的指望分數
狀態轉移:dp[i][0] = (1 - p[i]) * (dp[i-1][0] + dp[i-1][1])
dp[i][1] = ∑ ( ∏p[k](j < k <= i) * (dp[j][0] + (1 - p[j]) * (i - j)^m)) (0<= j < i)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e3 + 5; const int MOD = 1e9 + 7; LL p[N], pp[N], dp[N][2]; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%lld", &p[i]); for (int i = 0; i <= n; i++) p[i] = (p[i] * q_pow(100, MOD-2)) % MOD, pp[i] = (1 - p[i] + MOD) % MOD; dp[0][0] = dp[1][0] = 0; for (int i = 1; i <= n; i++) { LL t = p[i]; dp[i][1] = 0; for (int j = i-1; j >= 0; j--) { dp[i][1] = (dp[i][1] + t * (dp[j][0] + pp[j] * q_pow(i-j, m) % MOD) % MOD) % MOD; t = (t * p[j]) % MOD; } dp[i][0] = (pp[i] * (dp[i-1][0] + dp[i-1][1])) % MOD; } printf("%lld\n", (dp[n][1] + dp[n][0]) % MOD); return 0; }
思路:KMP
隊友代碼:
#include<bits/stdc++.h> using namespace std; long long dp[1010][2]; int nnxt[5][100010]; int ans[100010]; void init(int MIN){ for(int i=0;i<=100010;i++)ans[i]=MIN; } void getNext(string ptr, int next[]){ next[0] = -1; int j = 0, k = -1; while(j < ptr.size()){ if (k == -1 || ptr[j] == ptr[k]){ if (ptr[++j] == ptr[++k]) next[j] = next[k]; else next[j] = k; } else k = next[k]; } } int I[100010],J[100010]; bool match[100010]; int KMP(string now, string ptr,int next[]){ string str; int cnt = 0; int i = 0, j = 0; int pos = 0; while(pos < now.length()){ if(now[pos]=='-'){ if(str.length())str.pop_back(); i=I[str.length()],j=J[str.length()]; cnt+=match[str.length()]; pos++; if(match[str.length()])ans[pos]=0; else ans[pos]=min(ans[pos],(int)ptr.length()-j); // cout<<j<<' '; continue; } else{ str.push_back(now[pos]); match[str.length()]=0; while(i < str.size()){ if (j == -1 || str[i] == ptr[j]){ i++, j++; if (j == ptr.size()){ cnt++; j = next[j]; match[str.length()]=1; ans[pos+1]=0; //cout<<j<<endl; } } else j = next[j]; } I[str.length()]=i,J[str.length()]=j; pos++; ans[pos]=min(ans[pos],(int)ptr.length()-j); // cout<<j<<' '; } } return cnt; } int main(){ int n; string t[5]; string s; int MIN=0x7fffffff; cin>>n; for(int i=1;i<=n;i++){ cin>>t[i]; getNext(t[i],nnxt[i]); MIN=min(MIN,(int)t[i].length()); } init(0x7fffffff); cin>>s; for(int i=1;i<=n;i++){ // cout<<" "; KMP(s,t[i],nnxt[i]); // cout<<endl; // // cout<<endl; } cout<<MIN<<endl; for(int i=1;i<=s.length();i++)cout<<ans[i]<<endl; return 0; }
J Maze
思路:每次修改後這個位置的指望值不變,由於加上一個lowbit和減去一個lowbit後取平均值仍是原來的值。
隊友代碼:
#include<bits/stdc++.h> using namespace std; const long long mod=998244353; long long a[100010]; long long pre[100010]; long long POW(long long x,long long n){ long long re=1,base=x; while(n){ if(n&1)(re*=base)%=mod; (base*=base)%=mod; n>>=1; } return re; } int main(){ int T; int n,m; int u,v,w; scanf("%d",&T); for(int t=1;t<=T;t++){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld",a+i); } for(int i=1;i<=n;i++){ pre[i]=(pre[i-1]+a[i])%mod; } long long pp=POW(2ll,1ll*n*m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); if(u==2){ printf("%lld\n",((pre[w]-pre[v-1]+mod)%mod)*pp%mod); } } } return 0; }
B Rikka with Burrow-Wheeler Transform
思路:推出每一個位置i的k階前綴和的公式∑C(i+k-1, k)*a[j] (1 <= j <= i),而後用差分記錄第一種操做的修改(否則保存不下),將差分當作-1階的前綴和,而後查詢的時候將全部出現過的修改都用公式求一下前綴和查詢到修改之間有幾回第二種操做就是他的階數,記得要加1,由於咱們用差分記錄的。
隊友代碼:
#include<bits/stdc++.h> using namespace std; long long fac[200010],inv[200010]; const long long mod=998244353; int L[200010],R[200010],val[200010],cnt[200010],top,tot; long long POW(long long x,long long n){ long long re=1,base=x; while(n){ if(n&1)(re*=base)%=mod; (base*=base)%=mod; n>>=1; } return re; } long long C(long long n,long long m){ if(n<0||m<0||n<m)return 0; return fac[n]*inv[n-m]%mod*inv[m]%mod; } void init(){ top=0,tot=0; } void INIT(){ fac[0]=1; for(int i=1;i<=200001;i++)fac[i]=fac[i-1]*i%mod; inv[200001]=POW(fac[200001],mod-2); for(int i=200001;i>=1;i--)inv[i-1]=inv[i]*i%mod; } int main(){ INIT(); int T,n,m,op; int l,r,v; scanf("%d",&T); for(int t=1;t<=T;t++){ init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d",&l,&r,&v); L[top]=l,R[top]=r,val[top]=v,cnt[top++]=tot; } else if(op==2)tot++; else{ long long ans=0; scanf("%d%d",&l,&r); for(int j=0;j<top;j++){ ans+= C(r-L[j]+tot-cnt[j]+1,tot-cnt[j]+1)*val[j]%mod +C(r-R[j]-1+tot-cnt[j]+1,tot-cnt[j]+1)*(-val[j])%mod -C(l-1-L[j]+tot-cnt[j]+1,tot-cnt[j]+1)*val[j]%mod -C(l-1-R[j]-1+tot-cnt[j]+1,tot-cnt[j]+1)*(-val[j])%mod; ((ans%=mod)+=mod)%=mod; } cout<<ans<<endl; } } } return 0; }
思路:記錄下每一個字母的位置,而後合併時查找第一個可行的位置,而後更新可行區間。
隊友代碼:
#include<bits/stdc++.h> using namespace std; int idx(char c){ return c-'a'; } vector<int> pos[26]; int getPos(int id,int p){ if(lower_bound(pos[id].begin(),pos[id].end(),p)==pos[id].end())return -1; else return pos[id][lower_bound(pos[id].begin(),pos[id].end(),p)-pos[id].begin()]; } void init(){ for(int i=0;i<26;i++)pos[i].clear(); } char ans[1000010]; char s[1000010]; int main(){ int T,n,m; scanf("%d",&T); for(int t=1;t<=T;t++){ scanf("%d",&n); int tot=0; init(); for(int i=1;i<=n;i++){ scanf("%s",s); m=strlen(s); int ppos=0; for(int j=0;j<m;j++){ if(ppos==-1){ pos[idx(s[j])].push_back(tot); ans[tot++]=s[j]; } else{ ppos=(getPos(idx(s[j]),ppos)); if(ppos==-1){ pos[idx(s[j])].push_back(tot); ans[tot++]=s[j]; } else{ ppos++; } } } } ans[tot]=0; puts(ans); } return 0; }