Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)
A. Single Wildcard Pattern Matching
题解:记 “ * ”的位置为pos(假设存在),那么就顺着匹配 0 ~ (pos - 1),倒着匹配 (pos + 1) ~ n就行了,特判一下 n > m + 1 的情况 和 没有 “ * ”的情况。
题解:在1 ~ n中找大于 k / 2 + 1的数有多少个。
ps:因为给的串就已经是匹配的了,随便搞
题解:先把所有含0的位置预处理了:如果a序列中出现了q,那么随便一个出现0的位置填上q,然后顺着处理一遍0,逆着处理一遍0:
for (int i = 1; i <= n; ++i) if (!a[i]) a[i] = a[i - 1]; for (int i = n; i >= 1; --i) if (!a[i]) a[i] = a[i + 1];
每个数对应的最长区间:
for (int i = 1; i <= n; ++i) { Min[a[i]] = min(Min[a[i]], i); Max[a[i]] = max(Max[a[i]], i); }
最后线段树模拟一下询问的过程行了(每个数组的空间一定要开够,因为 use[ ] 只开了2e5,wa 10 wa到气哭)
#include<bits/stdc++.h> #define ULL unsigned long long #define LL long long #define P pair<int, int> #define pb push_back #define mp make_pair #define pp pop_back #define lson root << 1 #define INF32 (int)2e9 + 7 #define rson root << 1 | 1 #define INF64 (unsigned long long)1e18 #define sc(x) scanf("%d", &x) #define pr(x) printf("%d\n", x) #define mem(arry, in) memset(arry, in, sizeof(arry)) #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define BEGIN() int T; sc(T); while(T--) using namespace std; /* namespace fastIO { #define BUF_SIZE 100000 bool IOerror = 0; inline char nc() { static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE; if(p1 == pend) { p1 = buf; pend = buf + fread(buf, 1, BUF_SIZE, stdin); if(pend == p1) { IOerror = 1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; } inline void read(int &x) { char ch; while(blank(ch = nc())); if(IOerror) return; for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0'); } #undef BUF_SIZE }; using namespace fastIO; */ inline void upd(int &x, int y) { x < y && (x = y); } const int N = 200005; int n, q; int a[N], Min[N], Max[N], b[4 * N], use[4 * N]; void Inite() { mem(Max, 0), mem(use, 0); for (int i = 0; i < N; ++i) Min[i] = INF32; } void Pushdown(int root) { b[lson] = b[rson] = b[root]; b[root] = 0; use[lson] = use[rson] = 1; use[root] = 0; } void Update(int l, int r, int root, int L, int R, int x) { if (l > R || r < L) return; if (L <= l && r <= R) { b[root] = x; use[root] = 1; return; } if (use[root]) Pushdown(root); int mid = (l + r) >> 1; Update(l, mid, lson, L, R, x); Update(mid + 1, r, rson, L, R, x); } vector<int> res; void print(int l, int r, int root) { if (l == r) { res.pb(b[root]); return ; } if (use[root]) Pushdown(root); int mid = (l + r) >> 1; print(l, mid, lson); print(mid + 1, r, rson); } int main() { //freopen("D:\\a.in", "r", stdin); //freopen("D:\\1.txt", "w", stdout); Inite(); res.clear(); cin >> n >> q; int ps = -1; bool flag = 0; for (int i = 1; i <= n; ++i) { cin >> a[i]; if (a[i] == q) flag = 1; if (a[i] && ps == -1) ps = i; } if (ps == -1) { puts("YES"); for (int i = 1; i <= n; ++i) printf("%d ", q); return 0; } if (!flag) { bool vq = 0; for (int i = 1; i <= n; ++i) if (!a[i]) { a[i] = q; vq = 1; break; } if (!vq) { puts("NO"); return 0; } } for (int i = 1; i <= n; ++i) if (!a[i]) a[i] = a[i - 1]; for (int i = n; i >= 1; --i) if (!a[i]) a[i] = a[i + 1]; //for (int i = 1; i <= n; ++i) cout << a[i] << " "; //cout << endl; for (int i = 1; i <= n; ++i) { Min[a[i]] = min(Min[a[i]], i); Max[a[i]] = max(Max[a[i]], i); } for (int i = 1; i <= q; ++i) if (Min[i] != INF32) Update(1, n, 1, Min[i], Max[i], i); print(1, n, 1); for (int i = 0; i < res.size(); ++i) if (res[i] != a[i + 1]) { puts("NO"); return 0; } puts("YES"); for (auto x : res) printf("%d ", x); return 0; }
ps:从两头向中间找,如果(i,j)能到(n,n),那么(i + 1, j)能到(n,n)或者(i,j + 1)能到(n,n)。
inline void upd(int &x, int y) { x < y && (x = y); } const int N = 200005; int n, x, y; string s1 = "", s2 = ""; bool ask(int x1, int y1, int x2, int y2) { cout << "? " << x1 << " " << y1 << " " << x2 << " " << y2 << endl; string s; cin >> s; return s == "YES"; } int main() { //freopen("D:\\a.in", "r", stdin); //freopen("D:\\1.txt", "w", stdout); sc(n); x = 1, y = 1; int t = n - 1; while(t--) { if (ask(x + 1, y, n, n)) { x++; s1 = s1 + "D"; } else { y++; s1 = s1 + "R"; } } t = n - 1; x = n, y = n; while(t--) { if (ask(1, 1, x, y - 1)) { y--; s2 = "R" + s2; } else { x--; s2 = "D" + s2; } } cout << "! " << s1 + s2 << endl; return 0; }