题目质量不错的一场。
题目链接:https://codeforces.com/contest/1187
A:
水题。
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 q; 21 22 int main() { 23 cin >> q; 24 while (q--) { 25 int n, s, t; cin >> n >> s >> t; 26 int chong = s + t - n; s -= chong, t -= chong; 27 cout << max(s, t) + 1 << endl; 28 } 29 return 0; 30 }
B:
用数据结构维护s的每个字母出现的位置即可。
tag里的binary search怪怪的,我觉得ds才靠谱(
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 vector<int>v[26]; 21 string a, b; 22 int n, m, p = 0; 23 24 int main() { 25 cin >> n >> a; 26 for (auto i : a) v[i - 'a'].pb(++p); 27 cin >> m; 28 while (m--) { 29 cin >> b; 30 int cnt[26] = {0}; 31 for (auto i : b) cnt[i - 'a']++; 32 int ans = 0; 33 rep0(i, 0, 26) 34 if (cnt[i]) ans = max(ans, v[i][cnt[i] - 1]); 35 printf("%d ", ans); 36 } 37 return 0; 38 }
C:
考察每个区间,如果要求不下降,则给区间内每个成员打标记。然后看下降区间内有无未被标记成员,若无,则不可能构造。最后构造出来的数组不下降区间内所有成员大小相同即可,满足数组整体不上升。
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 = 1e3 + 10; 21 struct Interval { 22 int t, l, r; 23 Interval() {} 24 Interval(int a, int b, int c): t(a), l(b), r(c) {} 25 } v[maxn]; 26 int n, m, p = 0, ans = 1e8, flag = 1, a[maxn], b[maxn]; 27 28 int main() { 29 scanf("%d%d", &n, &m); 30 rep1(i, 1, m) { 31 scanf("%d%d%d", &v[i].t, &v[i].l, &v[i].r); 32 if (v[i].t == 1) 33 rep0(j, v[i].l, v[i].r) a[j] = 1; // sign 34 } 35 rep1(i, 1, m) 36 if (!v[i].t) { 37 flag = 0; 38 rep0(j, v[i].l, v[i].r) 39 if (!a[j]) { 40 flag = 1; break; 41 } 42 if (!flag) 43 return puts("NO"); 44 } 45 puts("YES"); 46 rep1(i, 1, n) printf("%d ", a[i - 1] ? ans : --ans); 47 puts(""); 48 return 0; 49 }
D:
用线段树维护数组a的区间最小值。另开一个vector<int>[]倒序记录数组中每个数字的出现位置。
O(n)遍历数组b,对于每一个b[i],检查从1到b[i]最先一次出现在a数组的位置(这个位置每使用一次会往后更新,看代码注释)这段区间内的最小值是否等于b[i]。若是,则有解,反之无解。
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 #define mid (curl+curr>>1) 17 /* namespace */ 18 using namespace std; 19 /* header end */ 20 21 const int maxn = 3e5 + 10; 22 int t, n, segt[maxn << 2], a[maxn], b[maxn]; 23 vector<int>pos[maxn]; 24 25 void build(int curpos, int curl, int curr) { 26 segt[curpos] = a[curl]; 27 if (curl == curr) return; 28 build(lson, curl, mid); build(rson, mid + 1, curr); 29 segt[curpos] = min(segt[lson], segt[rson]); 30 } 31 32 int query(int curpos, int curl, int curr, int ql, int qr) { 33 if (ql <= curl && curr <= qr) return segt[curpos]; 34 if (qr <= mid) return query(lson, curl, mid, ql, qr); 35 else if (ql > mid) return query(rson, mid + 1, curr, ql, qr); 36 else return min(query(lson, curl, mid, ql, mid), query(rson, mid + 1, curr, mid + 1, qr)); 37 } 38 39 void update(int curpos, int curl, int curr, int pos, int val) { 40 if (curl == curr) { 41 segt[curpos] = val; 42 return; 43 } 44 if (pos <= mid) update(lson, curl, mid, pos, val); 45 else update(rson, mid + 1, curr, pos, val); 46 segt[curpos] = min(segt[lson], segt[rson]); 47 } 48 49 int main() { 50 scanf("%d", &t); 51 while (t--) { 52 scanf("%d", &n); 53 rep1(i, 1, n) pos[i].clear(); 54 rep1(i, 1, n) scanf("%d", &a[i]); 55 for (int i = n; i > 0; i--) pos[a[i]].pb(i); 56 rep1(i, 1, n) scanf("%d", &b[i]); 57 int flag = 1; 58 build(1, 1, n); 59 rep1(i, 1, n) { 60 int k = b[i]; 61 if (pos[k].empty()) { // no element can be choisen to swap 62 flag = 0; break; 63 } 64 int x = *(--pos[k].end()); // get the last element of vector pos[k] 65 if (query(1, 1, n, 1, x) != k) { // the mininum of interval is not current b[i], no solution obviously 66 flag = 0; break; 67 } 68 update(1, 1, n, x, int_inf); // current b[i] is ok, make it into inf to eliminate the affect 69 } 70 if (flag) puts("YES"); else puts("NO"); 71 } 72 return 0; 73 }
E:
答案就是每个点的总度数+点数。跑一遍dfs即可。
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 #define mid (curl+curr>>1) 17 /* namespace */ 18 using namespace std; 19 /* header end */ 20 21 const int maxn = 5e5 + 10; 22 int n, top = 0, maxx, pos, cur; 23 ll ans = 0; 24 int head[maxn], nxt[maxn], edge[maxn], depth[maxn], size[maxn]; 25 26 void addEdge(int x, int y) { 27 edge[++top] = y; 28 nxt[top] = head[x]; 29 head[x] = top; 30 } 31 32 void dfs(int x, int fa) { 33 size[x] = 1; 34 for (int i = head[x]; i; i = nxt[i]) { 35 int v = edge[i]; 36 if (v == fa) continue; 37 depth[v] = depth[x] + 1; 38 dfs(v, x); 39 size[x] += size[v]; 40 } 41 } 42 43 void calc(int x, int fa, ll num) { 44 ans = max(ans, num); 45 for (int i = head[x]; i; i = nxt[i]) { 46 int v = edge[i]; 47 if (v == fa) continue; 48 calc(v, x, num + n - 2 * size[v]); 49 } 50 } 51 52 int main() { 53 scanf("%d", &n); 54 rep0(i, 1, n) { 55 int x, y; scanf("%d%d", &x, &y); 56 addEdge(x, y); addEdge(y, x); 57 } 58 depth[1] = 1; 59 dfs(1, 0); 60 ll num = 0; 61 rep1(i, 1, n) num += depth[i]; 62 calc(1, 0, num); 63 printf("%lld ", ans); 64 return 0; 65 }
F && G:
不会,摸了(