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。
