A. Math Problem
Description
给出n个区间,求一个最短区间使得这个区间与n个区间都有交集
Solution
对$l,r$排序,求出$l_{max}-r_{min}$即可。
做题时被这个卡,真的憨憨。
1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <iostream> 8 #include <map> 9 #include <numeric> 10 #include <queue> 11 #include <set> 12 #include <stack> 13 #if __cplusplus >= 201103L 14 #include <unordered_map> 15 #include <unordered_set> 16 #endif 17 #include <vector> 18 #define lson rt << 1, l, mid 19 #define rson rt << 1 | 1, mid + 1, r 20 #define LONG_LONG_MAX 9223372036854775807LL 21 #define pblank putchar(' ') 22 #define ll LL 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) 24 using namespace std; 25 typedef long long ll; 26 typedef long double ld; 27 typedef unsigned long long ull; 28 typedef pair<int, int> P; 29 int n, m, k; 30 const int maxn = 1e5 + 10; 31 template <class T> 32 inline T read() 33 { 34 int f = 1; 35 T ret = 0; 36 char ch = getchar(); 37 while (!isdigit(ch)) 38 { 39 if (ch == '-') 40 f = -1; 41 ch = getchar(); 42 } 43 while (isdigit(ch)) 44 { 45 ret = (ret << 1) + (ret << 3) + ch - '0'; 46 ch = getchar(); 47 } 48 ret *= f; 49 return ret; 50 } 51 template <class T> 52 inline void write(T n) 53 { 54 if (n < 0) 55 { 56 putchar('-'); 57 n = -n; 58 } 59 if (n >= 10) 60 { 61 write(n / 10); 62 } 63 putchar(n % 10 + '0'); 64 } 65 template <class T> 66 inline void writeln(const T &n) 67 { 68 write(n); 69 puts(""); 70 } 71 template <typename T> 72 void _write(const T &t) 73 { 74 write(t); 75 } 76 template <typename T, typename... Args> 77 void _write(const T &t, Args... args) 78 { 79 write(t), pblank; 80 _write(args...); 81 } 82 template <typename T, typename... Args> 83 inline void write_line(const T &t, const Args &... data) 84 { 85 _write(t, data...); 86 puts(""); 87 } 88 vector<int> l(maxn), r(maxn); 89 int main(int argc, char const *argv[]) 90 { 91 #ifndef ONLINE_JUDGE 92 freopen("in.txt", "r", stdin); 93 // freopen("out.txt", "w", stdout); 94 #endif 95 int t = read<int>(); 96 while (t--) 97 { 98 n = read<int>(); 99 for (int i = 0; i < n; i++) 100 l[i] = read<int>(), r[i] = read<int>(); 101 if (n == 1) 102 { 103 puts("0"); 104 continue; 105 } 106 sort(l.begin(), l.begin() + n); 107 sort(r.begin(), r.begin() + n); 108 writeln(max(l[n - 1] - r[0], 0)); 109 } 110 return 0; 111 }
B. Box
Description
给出一个序列表示当前起始到当前的最大值,问能否构造一个排列。
Solution
模拟即可,并查集维护下一个值。
1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <iostream> 8 #include <map> 9 #include <numeric> 10 #include <queue> 11 #include <set> 12 #include <stack> 13 #if __cplusplus >= 201103L 14 #include <unordered_map> 15 #include <unordered_set> 16 #endif 17 #include <vector> 18 #define lson rt << 1, l, mid 19 #define rson rt << 1 | 1, mid + 1, r 20 #define LONG_LONG_MAX 9223372036854775807LL 21 #define pblank putchar(' ') 22 #define ll LL 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) 24 using namespace std; 25 typedef long long ll; 26 typedef long double ld; 27 typedef unsigned long long ull; 28 typedef pair<int, int> P; 29 int n, m, k; 30 const int maxn = 1e5 + 10; 31 template <class T> 32 inline T read() 33 { 34 int f = 1; 35 T ret = 0; 36 char ch = getchar(); 37 while (!isdigit(ch)) 38 { 39 if (ch == '-') 40 f = -1; 41 ch = getchar(); 42 } 43 while (isdigit(ch)) 44 { 45 ret = (ret << 1) + (ret << 3) + ch - '0'; 46 ch = getchar(); 47 } 48 ret *= f; 49 return ret; 50 } 51 template <class T> 52 inline void write(T n) 53 { 54 if (n < 0) 55 { 56 putchar('-'); 57 n = -n; 58 } 59 if (n >= 10) 60 { 61 write(n / 10); 62 } 63 putchar(n % 10 + '0'); 64 } 65 template <class T> 66 inline void writeln(const T &n) 67 { 68 write(n); 69 puts(""); 70 } 71 template <typename T> 72 void _write(const T &t) 73 { 74 write(t); 75 } 76 template <typename T, typename... Args> 77 void _write(const T &t, Args... args) 78 { 79 write(t), pblank; 80 _write(args...); 81 } 82 template <typename T, typename... Args> 83 inline void write_line(const T &t, const Args &... data) 84 { 85 _write(t, data...); 86 puts(""); 87 } 88 int a[maxn]; 89 int res[maxn]; 90 map<int, int> mp; 91 set<int> s; 92 int fa[maxn]; 93 int find(int x) 94 { 95 if (fa[x] == 0) 96 return x; 97 return fa[x] = find(fa[x]); 98 } 99 int main(int argc, char const *argv[]) 100 { 101 #ifndef ONLINE_JUDGE 102 freopen("in.txt", "r", stdin); 103 // freopen("out.txt", "w", stdout); 104 #endif 105 int t = read<int>(); 106 while (t--) 107 { 108 mp.clear(); 109 s.clear(); 110 int f = 1; 111 n = read<int>(); 112 memset(fa, 0, sizeof(int) * (n + 1)); 113 memset(res, 0, sizeof(int) * (n + 1)); 114 for (int i = 1; i <= n; i++) 115 { 116 a[i] = read<int>(); 117 if (a[i] < i) 118 f = 0; 119 if (!mp[a[i]]) 120 { 121 res[i] = a[i]; 122 fa[a[i]] = a[i] + 1; 123 } 124 s.emplace(a[i]); 125 mp[a[i]]++; 126 } 127 if (f) 128 { 129 int p = 1; 130 for (int i = 1; i <= n; i++) 131 if (!res[i]) 132 { 133 res[i] = find(p); 134 fa[p] = res[i] + 1; 135 } 136 for (int i = 1; i <= n; i++) 137 write(res[i]), pblank; 138 puts(""); 139 } 140 else 141 puts("-1"); 142 } 143 return 0; 144 }
C. Messy
Description
给出一个括号字符串,每次可以进行操作将一段连续子串翻转。
求一种翻转方式使得翻转后的字符串恰好有k个前缀是匹配字符串。
匹配字符串就是可以正确放入数学表达式的括号串。
Solution
由于没有要求最少交换,直接暴力构造即可。
我选的构造前k-1个前缀是"()",最后一个前缀是这种"(((())))".
1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <iostream> 8 #include <map> 9 #include <numeric> 10 #include <queue> 11 #include <set> 12 #include <stack> 13 #if __cplusplus >= 201103L 14 #include <unordered_map> 15 #include <unordered_set> 16 #endif 17 #include <vector> 18 #define lson rt << 1, l, mid 19 #define rson rt << 1 | 1, mid + 1, r 20 #define LONG_LONG_MAX 9223372036854775807LL 21 #define pblank putchar(' ') 22 #define ll LL 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) 24 using namespace std; 25 typedef long long ll; 26 typedef long double ld; 27 typedef unsigned long long ull; 28 typedef pair<int, int> P; 29 int n, m, k; 30 const int maxn = 1e5 + 10; 31 template <class T> 32 inline T read() 33 { 34 int f = 1; 35 T ret = 0; 36 char ch = getchar(); 37 while (!isdigit(ch)) 38 { 39 if (ch == '-') 40 f = -1; 41 ch = getchar(); 42 } 43 while (isdigit(ch)) 44 { 45 ret = (ret << 1) + (ret << 3) + ch - '0'; 46 ch = getchar(); 47 } 48 ret *= f; 49 return ret; 50 } 51 template <class T> 52 inline void write(T n) 53 { 54 if (n < 0) 55 { 56 putchar('-'); 57 n = -n; 58 } 59 if (n >= 10) 60 { 61 write(n / 10); 62 } 63 putchar(n % 10 + '0'); 64 } 65 template <class T> 66 inline void writeln(const T &n) 67 { 68 write(n); 69 puts(""); 70 } 71 template <typename T> 72 void _write(const T &t) 73 { 74 write(t); 75 } 76 template <typename T, typename... Args> 77 void _write(const T &t, Args... args) 78 { 79 write(t), pblank; 80 _write(args...); 81 } 82 template <typename T, typename... Args> 83 inline void write_line(const T &t, const Args &... data) 84 { 85 _write(t, data...); 86 puts(""); 87 } 88 char s[maxn]; 89 int main(int argc, char const *argv[]) 90 { 91 #ifndef ONLINE_JUDGE 92 freopen("in.txt", "r", stdin); 93 // freopen("out.txt", "w", stdout); 94 #endif 95 int t = read<int>(); 96 while (t--) 97 { 98 vector<P> res; 99 res.clear(); 100 n = read<int>(); 101 k = read<int>(); 102 scanf("%s", s); 103 for (int i = 0; i < k - 1; i++) 104 { 105 int curx = i * 2; 106 if (s[curx] == '(') 107 { 108 if (s[curx + 1] == '(') 109 { 110 int tox = 0; 111 for (int j = curx + 2; j < n && !tox; j++) 112 if (s[j] == ')') 113 tox = j; 114 res.emplace_back(curx + 1, tox); 115 reverse(s + curx, s + tox + 1); 116 } 117 } 118 else 119 { 120 int tox = 0; 121 for (int j = curx + 1; j < n && !tox; j++) 122 if (s[j] == '(') 123 tox = j; 124 res.emplace_back(curx, tox); 125 reverse(s + curx, s + tox + 1); 126 i--; 127 } 128 } 129 int tox = k - 1 << 1; 130 int left = n - tox >> 1; 131 for (int i = tox, j = 0; i < n; i++, j++) 132 { 133 if (j < left) 134 { 135 if (s[i] == ')') 136 { 137 int tx = 0; 138 for (int q = i + 1; q < n && !tx; q++) 139 if (s[q] == '(') 140 tx = q; 141 res.emplace_back(i, tx); 142 reverse(s + i, s + tx + 1); 143 } 144 } 145 } 146 writeln(res.size()); 147 for (auto x : res) 148 write_line(x.first + 1, x.second + 1); 149 } 150 return 0; 151 }
D2. Optimal Subsequences (Hard Version)
Description
给出一个长为n的序列。
m次查询,每次查询给出两个值k,p。
要求找出序列长度为k,累加和最大且字典序最小的子序列中的第p个数。
Solution
D1,数据小,暴力开冲。
D2,对原序列按值和idx排序,对查询按找k值排序,离线查询。
对每次查询,先将排序后的值序列前k个的idx插入树状数组,二分找出第p个值得idx,记为当前查询答案。
1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <iostream> 8 #include <map> 9 #include <numeric> 10 #include <queue> 11 #include <set> 12 #include <stack> 13 #if __cplusplus >= 201103L 14 #include <unordered_map> 15 #include <unordered_set> 16 #endif 17 #include <vector> 18 #define lson rt << 1, l, mid 19 #define rson rt << 1 | 1, mid + 1, r 20 #define LONG_LONG_MAX 9223372036854775807LL 21 #define pblank putchar(' ') 22 #define ll LL 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) 24 using namespace std; 25 typedef long long ll; 26 typedef long double ld; 27 typedef unsigned long long ull; 28 typedef pair<int, int> P; 29 int n, m, k; 30 const int maxn = 2e5 + 10; 31 template <class T> 32 inline T read() 33 { 34 int f = 1; 35 T ret = 0; 36 char ch = getchar(); 37 while (!isdigit(ch)) 38 { 39 if (ch == '-') 40 f = -1; 41 ch = getchar(); 42 } 43 while (isdigit(ch)) 44 { 45 ret = (ret << 1) + (ret << 3) + ch - '0'; 46 ch = getchar(); 47 } 48 ret *= f; 49 return ret; 50 } 51 template <class T> 52 inline void write(T n) 53 { 54 if (n < 0) 55 { 56 putchar('-'); 57 n = -n; 58 } 59 if (n >= 10) 60 { 61 write(n / 10); 62 } 63 putchar(n % 10 + '0'); 64 } 65 template <class T> 66 inline void writeln(const T &n) 67 { 68 write(n); 69 puts(""); 70 } 71 template <typename T> 72 void _write(const T &t) 73 { 74 write(t); 75 } 76 template <typename T, typename... Args> 77 void _write(const T &t, Args... args) 78 { 79 write(t), pblank; 80 _write(args...); 81 } 82 template <typename T, typename... Args> 83 inline void write_line(const T &t, const Args &... data) 84 { 85 _write(t, data...); 86 puts(""); 87 } 88 P a[maxn]; 89 struct Node 90 { 91 int first, second, idx; 92 Node(int a, int b, int c) : first(a), second(b), idx(c) {} 93 Node() {} 94 bool operator<(const Node &t) const 95 { 96 return first < t.first; 97 } 98 } q[maxn]; 99 inline int lowbit(int x) 100 { 101 return x & (-x); 102 } 103 struct Ftree 104 { 105 int c[maxn]; 106 void add(int x) 107 { 108 while (x < maxn) 109 { 110 ++c[x]; 111 x += lowbit(x); 112 } 113 } 114 int query(int x) 115 { 116 int res = 0; 117 while (x) 118 { 119 res += c[x]; 120 x -= lowbit(x); 121 } 122 return res; 123 } 124 } tree; 125 int cmp(const P &a, const P &b) 126 { 127 if (a.first == b.first) 128 return a.second < b.second; 129 return a.first > b.first; 130 } 131 int res[maxn], tmp[maxn]; 132 inline int judge(int x, int q) 133 { 134 return tree.query(x) >= q; 135 } 136 int main(int argc, char const *argv[]) 137 { 138 #ifndef ONLINE_JUDGE 139 freopen("in.txt", "r", stdin); 140 // freopen("out.txt", "w", stdout); 141 #endif 142 n = read<int>(); 143 for (int i = 1; i <= n; i++) 144 { 145 int x = read<int>(); 146 a[i] = P(x, i); 147 } 148 for (int i = 1; i <= n; i++) 149 tmp[i] = a[i].first; 150 sort(a + 1, a + 1 + n, cmp); 151 m = read<int>(); 152 for (int i = 1; i <= m; i++) 153 { 154 int k = read<int>(), p = read<int>(); 155 q[i] = Node(k, p, i); 156 } 157 sort(q + 1, q + 1 + m); 158 for (int i = 1, j = 1; i <= m; i++) 159 { 160 while (j <= q[i].first) 161 tree.add(a[j++].second); 162 int l = 1, r = n, cur = 0; 163 while (l <= r) 164 { 165 int mid = l + r >> 1; 166 if (judge(mid, q[i].second)) 167 cur = mid, r = mid - 1; 168 else 169 l = mid + 1; 170 } 171 res[q[i].idx] = tmp[cur]; 172 } 173 for (int i = 1; i <= m; i++) 174 writeln(res[i]); 175 return 0; 176 }
five。