这场真的是ICPC之耻,题目居然直接抄去年宁夏现场赛题,导致短短半个小时一片ak,真的让人说不出话。如果国内ACM从此走向没落,宁夏理工学院绝对有其不可推卸的责任!
虽然如此,但题目质量不错,题解还是要写的。
题目链接:https://www.jisuanke.com/contest/2991 (cf gym 也有)
A:
solver:czq
单调栈维护操作数最大值即可。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 int n, p, q, m; 21 ll ans; 22 stack<ll> st; 23 unsigned int SA, SB, SC; 24 25 unsigned int rng61() { 26 SA ^= SA << 16; 27 SA ^= SA >> 5; 28 SA ^= SA << 1; 29 unsigned int t = SA; 30 SA = SB; 31 SB = SC; 32 SC ^= t ^ SA; 33 return SC; 34 } 35 36 void gen() { 37 scanf("%d%d%d%d%u%u%u", &n, &p, &q, &m, &SA, &SB, &SC); 38 for (int i = 1; i <= n; i++) { 39 if (rng61() % (p + q) < p) { 40 int x = rng61() % m + 1; 41 if (!(int)st.size()) st.push(x); 42 else if (x > st.top()) st.push(x); 43 else st.push(st.top()); 44 } else { 45 if ((int)st.size()) st.pop(); 46 else continue; 47 } 48 if ((int)st.size()) ans ^= i * st.top(); 49 } 50 } 51 52 int main(void) { 53 int t; 54 scanf("%d", &t); 55 for (int i = 1; i <= t; i++) { 56 while ((int)st.size()) st.pop(); 57 ans = 0; 58 gen(); 59 printf("Case #%d: %lld ", i, ans); 60 } 61 return 0; 62 }
B:
solver:rsq
不停地计算旋转一次所依赖的扇形半径和角度,维护ans即可。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const double pi = acos(-1.0); 21 22 struct Point { 23 double x, y, len; 24 }; 25 26 double distant(Point a, Point b) { 27 return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2)); 28 } 29 30 double getAngle(Point a, Point b) { 31 return acos((a.x * b.x + a.y * b.y) / (a.len * b.len)); 32 } 33 34 int main() { 35 int t; scanf("%d", &t); 36 for (int __ = 1; __ <= t; __++) { 37 int n; scanf("%d", &n); 38 vector<Point> a(n), v(n); 39 for (auto &i : a) scanf("%lf%lf", &i.x, &i.y); 40 for (int i = 0; i < n - 1; i++) { 41 v[i].x = a[i + 1].x - a[i].x; 42 v[i].y = a[i + 1].y - a[i].y; 43 v[i].len = distant(a[i + 1], a[i]); 44 } 45 v[n - 1].x = a[0].x - a[n - 1].x; 46 v[n - 1].y = a[0].y - a[n - 1].y; 47 v[n - 1].len = distant(a[0], a[n - 1]); 48 Point g; scanf("%lf%lf", &g.x, &g.y); 49 double ans = 0.0, r = distant(g, a[0]); 50 ans += abs(getAngle(v[n - 1], v[0]) * r); 51 for (int i = 0; i < n - 1; i++) { 52 double r = distant(g, a[i + 1]); 53 ans += abs(getAngle(v[i], v[i + 1]) * r); 54 } 55 printf("Case #%d: %.3f ", __, ans); 56 } 57 return 0; 58 }
C:
solver:zyh, czq
送的水题。
1 /* Contest yinchuan_2019_online 2 * Problem C 3 * Team: Make One For Us 4 */ 5 #include <bits/stdc++.h> 6 7 using namespace std; 8 9 int main(void) { 10 ios::sync_with_stdio(false); 11 cin.tie(nullptr); 12 int T; 13 cin >> T; 14 for (int i = 1; i <= T; i++) { 15 cout << "Case #" << i << ": "; 16 int n, m; 17 cin >> n >> m; 18 string a, b, c; 19 cin >> a >> b >> c; 20 int delta = (b[0] - a[0] + 26) % 26; 21 for (auto e : c) { 22 char k = e - delta; 23 if (k < 'A') 24 k += 26; 25 cout << k; 26 } 27 cout << endl; 28 } 29 return 0; 30 }
D:
solver::zyh, rsq
第一个子问题的答案永远是1/2,第二个子问题的答案就是((m-1)/2+1)/m。
推理倒是挺妙,可惜我不会数学题(逃
1 /* Contest yinchuan_2019_online 2 * Problem D 3 * Team: Make One For Us 4 */ 5 #include <bits/stdc++.h> 6 7 using namespace std; 8 9 int main(void) { 10 ios::sync_with_stdio(false); 11 cin.tie(nullptr); 12 int T; 13 scanf("%d", &T); 14 for (int i = 1; i <= T; i++) { 15 int n, m; 16 scanf("%d %d", &n, &m); 17 printf("Case #%d: %.6f %.6f ", i, n == 1 ? 1 : 1.0 / 2, m == 1 ? 1 : ((double) (m - 1) / 2 + 1) / m); 18 } 19 return 0; 20 }
E:
solver:czq
读懂题就是个细节很多的大模拟。给定2-3-4树的构造方法,要求输出这棵树的前序遍历。
看到别人的写法比我的好多了……
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 1e5 + 5; 21 int a[maxn]; 22 int cnt, root; 23 24 struct Node { 25 int fa; 26 vector<int>deg, chd; 27 void init(int _fa, int curr) { 28 fa = _fa; 29 deg.clear(), chd.clear(); 30 deg.pb(curr); 31 } 32 } balt[maxn]; 33 34 void insert(int pos, int curr) { 35 if ((int)balt[pos].deg.size() == 3) { // need to split 36 int currfa = balt[pos].fa; 37 vector<int>vd, vch; 38 vd.swap(balt[pos].deg), vch.swap(balt[pos].chd); 39 if (pos == root) { 40 root = ++cnt; 41 balt[root].init(0, vd[1]); 42 balt[++cnt].init(root, vd[0]); 43 balt[pos].init(root, vd[2]); 44 balt[root].chd.pb(cnt), balt[root].chd.pb(pos); 45 if ((int)vch.size()) { 46 balt[cnt].chd.pb(vch[0]), balt[vch[0]].fa = cnt; 47 balt[cnt].chd.pb(vch[1]), balt[vch[1]].fa = cnt; 48 balt[pos].chd.pb(vch[2]), balt[vch[2]].fa = pos; 49 balt[pos].chd.pb(vch[3]), balt[vch[3]].fa = pos; 50 } 51 pos = root; 52 } else { // no need to split, but have father 53 balt[pos].init(currfa, vd[0]); 54 balt[++cnt].init(currfa, vd[2]); 55 balt[currfa].deg.pb(vd[1]); 56 sort(balt[currfa].deg.begin(), balt[currfa].deg.end()); 57 balt[currfa].chd.pb(cnt); 58 for (int i = (int)balt[currfa].chd.size() - 1; i > 1; i--) { 59 if (balt[currfa].chd[i - 1] != pos) swap(balt[currfa].chd[i - 1], balt[fa].chd[i]); 60 else break; 61 } 62 if ((int)vch.size()) { 63 balt[pos].chd.pb(vch[0]), balt[vch[0]].fa = pos; 64 balt[pos].chd.pb(vch[1]), balt[vch[1]].fa = pos; 65 balt[cnt].chd.pb((vch[2])), balt[vch[2]].fa = cnt; 66 balt[cnt].chd.pb(vch[3]), balt[vch[3]].fa = cnt; 67 } 68 pos = currfa; 69 } 70 } 71 if (!(int)balt[pos].chd.size()) { // have no child, no need to compare 72 balt[pos].deg.pb(curr); 73 sort(balt[pos].deg.begin(), balt[pos].deg.end()); 74 } else { // need to compare 75 if (curr < balt[pos].deg[0]) insert(balt[pos].chd[0], curr); 76 else if (curr > balt[pos].deg[(int)balt[pos].deg.size() - 1]) insert(balt[pos].chd[(int)balt[pos].chd.size() - 1], curr); 77 else { 78 for (int i = 1; i < (int)balt[pos].deg.size(); i++) 79 if (curr < balt[pos].deg[i]) { 80 insert(balt[pos].chd[i], curr); 81 break; 82 } 83 } 84 } 85 } 86 87 void dfs(int pos) { 88 for (int i = 0; i < (int)balt[pos].deg.size(); i++) 89 printf("%d%c", balt[pos].deg[i], i == (int)balt[pos].deg.size() - 1 ? ' ' : ' '); 90 for (int i = 0; i < (int)balt[pos].chd.size(); i++) dfs(balt[pos].chd[i]); 91 } 92 93 int main() { 94 int t; scanf("%d", &t); 95 for (int __ = 1; __ <= t; __++) { 96 int n; scanf("%d", &n); 97 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 98 cnt = root = 1, balt[root].init(0, a[1]); 99 for (int i = 2; i <= n; i++) insert(root, a[i]); 100 printf("Case #%d: ", __); 101 dfs(root); 102 } 103 return 0; 104 }
H:
upsolved:czq
sb贪心。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 1e5 + 10; 21 struct Monster { 22 int hp, atk; 23 Monster() {} 24 25 bool operator<(const Monster &rhs)const { 26 ll x = ceil((sqrt(1.0 + 8.0 * hp) - 1) / 2.0); 27 ll y = ceil((sqrt(1.0 + 8.0 * rhs.hp) - 1) / 2.0); 28 if ((ll)atk * y == (ll)rhs.atk * x) 29 return atk > rhs.atk; 30 return atk * y > rhs.atk * x; 31 } 32 } m[maxn]; 33 ll sum[maxn]; 34 35 int main() { 36 int t; scanf("%d", &t); 37 for (int __ = 1; __ <= t; __++) { 38 ll ans = 0, turn = 0; 39 int n; scanf("%d", &n); 40 for (int i = 0; i < n; i++) scanf("%d%d", &m[i].hp, &m[i].atk); 41 sort(m, m + n); 42 for (int i = 0; i <= n + 1; i++) sum[i] = 0; 43 for (int i = n - 1; i >= 0; i--) 44 sum[i] += sum[i + 1] + m[i].atk; 45 for (int i = 0; i < n; i++) { 46 turn = (ll)ceil((sqrt(1.0 + 8.0 * m[i].hp) - 1) / 2.0); 47 ans += sum[i] * turn; 48 } 49 printf("Case #%d: %lld ", __, ans); 50 } 51 return 0; 52 }
L:
solver:czq
给定一个长度为n的数组,计算有多少个这样的区间,对区间内元素排序后相邻元素之差不超过1。
线段树+单调栈。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 1e5 + 10; 21 int n, a[maxn]; 22 map<int, int>last; 23 pair<int, int> x[maxn], y[maxn]; 24 25 struct Node { 26 ll minn, t, lazy; 27 Node() {} 28 Node(int a, int b, int c): minn(a), t(b), lazy(c) {} 29 } segt[maxn << 2]; 30 31 void maintain(int curpos) { 32 segt[curpos].minn = min(segt[lson].minn, segt[rson].minn); 33 } 34 35 void pushdown(int curpos) { 36 segt[lson].lazy += segt[curpos].lazy; 37 segt[rson].lazy += segt[curpos].lazy; 38 segt[lson].minn += segt[curpos].lazy; 39 segt[rson].minn += segt[curpos].lazy; 40 segt[curpos].lazy = 0; 41 } 42 43 void build(int curpos, int curl, int curr) { 44 segt[curpos] = Node(0, 0, 0); 45 if (curl == curr) { 46 segt[curpos].t = 1; 47 return; 48 } 49 int mid = curl + curr >> 1; 50 build(lson, curl, mid); build(rson, mid + 1, curr); 51 } 52 53 void update(int curpos, int curl, int curr, int ql, int qr, ll val) { 54 if (ql == curl && curr == qr) { 55 segt[curpos].lazy += val; 56 segt[curpos].minn += val; 57 return; 58 } 59 if (segt[curpos].lazy) pushdown(curpos); 60 int mid = curl + curr >> 1; 61 if (qr <= mid) update(lson, curl, mid, ql, qr, val); 62 else if (ql > mid) update(rson, mid + 1, curr, ql, qr, val); 63 else { // maintain both 64 update(lson, curl, mid, ql, mid, val); 65 update(rson, mid + 1, curr, mid + 1, qr, val); 66 } 67 maintain(curpos); 68 if (segt[lson].minn == segt[rson].minn) 69 segt[curpos].t = segt[lson].t + segt[rson].t; 70 else if (segt[rson].minn == segt[curpos].minn) 71 segt[curpos].t = segt[rson].t; 72 else if (segt[lson].minn == segt[curpos].minn) 73 segt[curpos].t = segt[lson].t; 74 } 75 76 pair<int, int> solve(int curpos, int curl, int curr, int ql, int qr) { 77 if (ql == curl && qr == curr) 78 return mp(segt[curpos].minn, segt[curpos].t); 79 if (segt[curpos].lazy) pushdown(curpos); 80 int mid = curl + curr >> 1; 81 if (qr <= mid) return solve(lson, curl, mid, ql, qr); 82 else if (ql > mid) return solve(rson, mid + 1, curr, ql, qr); 83 else { 84 pair<int, int> lp = solve(lson, curl, mid, ql, mid); 85 pair<int, int> rp = solve(rson, mid + 1, curr, mid + 1, qr); 86 if (lp.first == rp.first) 87 return mp(lp.first, lp.second + rp.second); 88 return min(lp, rp); 89 } 90 } 91 92 int main() { 93 int t; scanf("%d", &t); 94 for (int __ = 1; __ <= t; __++) { 95 ll ans = 0; 96 last.clear(); 97 scanf("%d", &n); 98 build(1, 1, n); 99 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 100 int p1 = 0, p2 = 0; 101 for (int i = 1; i <= n; i++) { 102 while (p1 && a[i] > x[p1].first) { 103 update(1, 1, n, x[p1 - 1].second + 1, x[p1].second, a[i] - x[p1].first); 104 p1--; 105 } 106 x[++p1] = mp(a[i], i); 107 while (p2 && a[i] < y[p2].first) { 108 update(1, 1, n, y[p2 - 1].second + 1, y[p2].second, y[p2].first - a[i]); 109 p2--; 110 } 111 y[++p2] = mp(a[i], i); 112 update(1, 1, n, last[a[i]] + 1, i, -1); 113 last[a[i]] = i; 114 pair<int, int> curr = solve(1, 1, n, 1, i); 115 if (curr.first == -1) ans += curr.second; 116 } 117 printf("Case #%d: %lld ", __, ans); 118 } 119 return 0; 120 }