B. Social Network
Description
模拟一个FIFO页面置换算法,输出最后留在内存的页面
Solution
deque+set模拟。
先交了一发unordered_set,卡在了test 22。
改成set交过了。
在cf找了一篇讲unordered_set防止被卡的博客,改了之后也能ac。
1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <iostream> 8 #include <list> 9 #include <map> 10 #include <numeric> 11 #include <queue> 12 #include <set> 13 #include <stack> 14 #include <vector> 15 #include<chrono> 16 #include<unordered_set> 17 #define lson rt << 1, l, mid 18 #define rson rt << 1 | 1, mid + 1, r 19 #define LONG_LONG_MAX 9223372036854775807LL 20 #define pblank putchar(' ') 21 #define ll LL 22 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) 23 using namespace std; 24 typedef long long ll; 25 typedef long double ld; 26 typedef unsigned long long ull; 27 typedef pair<int, int> P; 28 int n, m, k; 29 const int maxn = 2e5 + 10; 30 template <class T> 31 inline T read() 32 { 33 int f = 1; 34 T ret = 0; 35 char ch = getchar(); 36 while (!isdigit(ch)) 37 { 38 if (ch == '-') 39 f = -1; 40 ch = getchar(); 41 } 42 while (isdigit(ch)) 43 { 44 ret = (ret << 1) + (ret << 3) + ch - '0'; 45 ch = getchar(); 46 } 47 ret *= f; 48 return ret; 49 } 50 template <class T> 51 inline void write(T n) 52 { 53 if (n < 0) 54 { 55 putchar('-'); 56 n = -n; 57 } 58 if (n >= 10) 59 { 60 write(n / 10); 61 } 62 putchar(n % 10 + '0'); 63 } 64 template <class T> 65 inline void writeln(const T &n) 66 { 67 write(n); 68 puts(""); 69 } 70 template <typename T> 71 void _write(const T &t) 72 { 73 write(t); 74 } 75 template <typename T, typename... Args> 76 void _write(const T &t, Args... args) 77 { 78 write(t), pblank; 79 _write(args...); 80 } 81 template <typename T, typename... Args> 82 inline void write_line(const T &t, const Args &... data) 83 { 84 _write(t, data...); 85 } 86 struct custom_hash 87 { 88 static uint64_t splitmix64(uint64_t x) 89 { 90 x += 0x9e3779b97f4a7c15; 91 x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 92 x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 93 return x ^ (x >> 31); 94 } 95 96 size_t operator()(uint64_t x) const 97 { 98 static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 99 return splitmix64(x + FIXED_RANDOM); 100 } 101 }; 102 unordered_set<int,custom_hash> s; 103 deque<int> q; 104 int main(int argc, char const *argv[]) 105 { 106 #ifndef ONLINE_JUDGE 107 freopen("in.txt", "r", stdin); 108 // freopen("out.txt","w", stdout); 109 #endif 110 n = read<int>(), k = read<int>(); 111 for (int i = 0; i < n; i++) 112 { 113 int x = read<int>(); 114 if (s.count(x)) 115 continue; 116 if (s.size() < k) 117 q.push_front(x), s.emplace(x); 118 else 119 { 120 s.erase(q[k - 1]); 121 s.emplace(x); 122 q.push_front(x); 123 } 124 } 125 int sz = s.size(); 126 writeln(sz); 127 for (int i = 0; i < sz; i++) 128 write(q[i]), pblank; 129 return 0; 130 }
C. Pipes
给出六种水管,每种都可以旋转。
给出两排相同数目的不同水管,问从(0,0)横向进来的水能否横向流出(1,n)
Solution
分析题目发现只要对于第一排和第二排,如果第一排和第二排都对应位置是3,4,5,6这些水管,
那么第一二排可以交换,这里的交换指,
我从(0,2)横向流到(0,3)的水,如果(0,3)和(1,3)都是3,4,5,6种,那么水流就会留到(1,3)继续往右。
而如果不是这样的话,就只能往右流或者流不动。
也就是说往右走水流是固定了的,那么从前往后扫一遍即可。
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 } 87 int dp[2][maxn]; 88 char s[2][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 fastIO; 96 int t; 97 cin >> t; 98 while(t--){ 99 cin >> n; 100 cin >> s[0] >> s[1]; 101 int cur = 0, f = 1; 102 for (int i = 0; i < n&&f;i++){ 103 int now = s[cur][i] - '0'; 104 if (now>2){ 105 cur ^= 1; 106 if (s[cur][i]-'0'<3) 107 f = 0; 108 } 109 } 110 if (f&&cur) 111 puts("YES"); 112 else 113 puts("NO"); 114 } 115 return 0; 116 }
D. Distinct Characters Queries
Description
给出一个只包含26个小写字母的字符串。
多次询问,每次可以将某一个位置的字符串换成另外一种,或者查询l,r字串里不同字符的数目。
Solution
对每一个字母建立一棵线段树,单点更新,查询区间和。
题解是用set
同样也是建立26个set,每个set里存储当前字母的位置。
更新操作时原字母erase,新字母insert。
查询时使用lower_bound查找大于等于l的值x,如果$x leq r$则计入答案。
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 19 #define rson rt << 1 | 1 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 } 87 char s[maxn]; 88 struct segTree 89 { 90 char ch; 91 void setCh(char p) { ch = p; } 92 struct node 93 { 94 int l, r; 95 int sum; 96 } tr[maxn << 2]; 97 inline void pushup(int rt) 98 { 99 tr[rt].sum = tr[lson].sum + tr[rson].sum; 100 } 101 void build(int rt, int l, int r) 102 { 103 tr[rt].l = l; 104 tr[rt].r = r; 105 if (l == r) 106 { 107 tr[rt].sum = s[l] == ch; 108 return; 109 } 110 int mid = l + r >> 1; 111 build(lson, l, mid); 112 build(rson, mid + 1, r); 113 pushup(rt); //一定要更新父节点 114 } 115 void update(int rt, int L, int x) 116 { 117 int l = tr[rt].l; 118 int r = tr[rt].r; 119 if (l == r) 120 { 121 tr[rt].sum += x; 122 return; 123 } 124 int mid = l + r >> 1; 125 if (mid >= L) 126 update(lson, L, x); 127 else 128 update(rson, L, x); 129 pushup(rt); 130 } 131 ll query(int rt, int L, int R) 132 { 133 int l = tr[rt].l; 134 int r = tr[rt].r; 135 if (l >= L && r <= R) 136 return tr[rt].sum; 137 int mid = l + r >> 1; 138 ll ans = 0; 139 if (L <= mid) 140 ans += query(lson, L, R); 141 if (R > mid) 142 ans += query(rson, L, R); 143 return ans; 144 } 145 } seg[27]; 146 int main(int argc, char const *argv[]) 147 { 148 #ifndef ONLINE_JUDGE 149 freopen("in.txt", "r", stdin); 150 // freopen("out.txt","w", stdout); 151 #endif 152 cin >> s + 1; 153 int len = strlen(s + 1); 154 for (int i = 0; i < 26; i++) 155 { 156 seg[i].setCh('a' + i); 157 seg[i].build(1, 1, len); 158 } 159 int t = read<int>(); 160 while (t--) 161 { 162 int op, l, r; 163 cin >> op >> l; 164 if (op == 1) 165 { 166 char r; 167 cin >> r; 168 seg[s[l] - 'a'].update(1, l, -1); 169 seg[r - 'a'].update(1, l, 1); 170 s[l] = r; 171 } 172 else 173 { 174 cin >> r; 175 int res = 0; 176 for (int i = 0; i < 26; i++) 177 { 178 int cur = seg[i].query(1, l, r); 179 if (cur) 180 ++res; 181 } 182 cout << res << " "; 183 } 184 } 185 return 0; 186 }
F. Yet Another Substring Reverse
Description
给一个只包含前20个小写字母的字符串,可以最多翻转一个子串。
求最长的子串,该子串里的所有字符皆不同。
Solution
补题。
由于只包含20个字符,显然答案最大为20。
预处理所有的最长互异字串,利用状态压缩保存信息。
令$dp[cur]=cnt$表示状态cur里的连续互异字符的个数。
最开始初始化时,如果dp[cur]有值,dp[cur]=__builtin_popcount(cur),
原串中有某子串满足包含且仅包含有cur的二进制为1的字符,$0-a,1-b,2-c...$
abacaba,对于这样一个字符串,初始时dp数组为
$dp[0]=0,dp[1]=1,dp[2]=1,dp[3]=2,dp[4]=1,dp[5]=2,dp[6]=0,dp[7]=3$
1代表包含${a}$,2代表包含${b}$,3代表包含${a,b}$,4代表包含${c}$,5代表包含${a,c}$,6代表包含${b,c}$,7代表包含${a,b,c}$
注意到6是没有值的,因为abacaba中没有一个符合题意的子串满足包含${b,c}$
然后为原本没有值状态寻找dp值最大的子状态。
即对于状态6而言,我们可以发现虽然没有完全包含${b,c}$的子串,但有仅包含$b$或者$c$的,那么更新6的dp值。
最后统计答案时,由于我们可以有一次的翻转操作,那么一个状态可以通过翻转和它的补集状态完美衔接。
所以最后扫一遍所有状态取最大值就是答案。
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 = 1e6 + 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 } 87 char s[maxn]; 88 const int state = (1 << 20) - 1; 89 int dp[state + 10]; 90 int main(int argc, char const *argv[]) 91 { 92 #ifndef ONLINE_JUDGE 93 freopen("in.txt", "r", stdin); 94 // freopen("out.txt", "w", stdout); 95 #endif 96 fastIO; 97 cin >> s; 98 n = strlen(s); 99 for (int i = 0; i < n; i++) 100 { 101 int cur = 0, cnt = 0; 102 for (int j = i; j < n; j++) 103 { 104 int now = s[j] - 'a'; 105 if (cur & (1 << now)) 106 break; 107 cur |= 1 << now; 108 ++cnt; 109 dp[cur] = cnt; 110 } 111 } 112 for (int i = 1; i <= state; i++) 113 for (int j = 0; j < 20; j++) 114 if (i & (1 << j)) 115 dp[i] = max(dp[i], dp[i ^ (1 << j)]); 116 int res = 0; 117 for (int i = 1; i <= state; i++) 118 res = max(res, dp[i] + dp[state ^ i]); 119 cout << res << " "; 120 return 0; 121 }