比较水的一场。
题目链接:https://www.jisuanke.com/contest/3005?view=challenges
A:
CRT可以抄板子解决,就算看不出斐波那契博弈,推一下必胜必败点就能猜出来。
可惜当时在切M,推完SG来不及做。待补。
B:
被卡常卡飞的题,最后还是卡常搞过去的。明明都是并查集为啥我们T飞啊。
1 /* Contest xuzhou_2019_online 2 * Problem B 3 * Team: Make One For Us 4 */ 5 #include6 7 using namespace std; 8 9 int read(void) { 10 char ch; 11 do { 12 ch = getchar(); 13 } while (!isdigit(ch)); 14 int ret = 0; 15 while (isdigit(ch)) { 16 ret *= 10; 17 ret += ch - '0'; 18 ch = getchar(); 19 }; 20 return ret; 21 } 22 23 struct range { 24 int l, r; 25 bool operator < (const range &r) const { 26 return l < r.l; 27 } 28 }; 29 30 int main(void) { 31 int n, q; 32 n = read(); 33 q = read(); 34 unordered_map <int, int> mp; 35 vector int, int>> query(q); 36 // vector nums(2 * q + 1); 37 setst; 38 // nums[0] = -1; 39 for (int i = 0; i < q; i++) { 40 query[i].first = read(); 41 query[i].second = read(); 42 // nums[1 + i] = query[i].second; 43 // nums[1 + i + q] = query[i].second + 1; 44 } 45 // nums.emplace_back(n + 1); 46 // sort(nums.begin(), nums.end()); 47 // nums.resize(unique(nums.begin(), nums.end()) - nums.begin()); 48 // for (unsigned int i = 0; i < nums.size(); i++) { 49 // mp[nums[i]] = i; 50 // } 51 // for (int i = 0; i < q; i++) { 52 // query[i].second = mp[query[i].second]; 53 // } 54 for (int i = 0; i < q; i++) { 55 // for (auto e: st) { 56 // cout << e.l << ", " << e.r << endl; 57 // cout << "_____________" << endl; 58 // } 59 auto t = query[i].second; 60 if (query[i].first == 1) { 61 // delete nums[t] 62 auto next = st.upper_bound({t, 0}); 63 range nxt = {t, t}; 64 if (next != st.begin()) { // 它有前驱(prev)也有后继(next) 65 auto prev = next; 66 prev--; 67 if (prev->l <= t && t <= prev->r) { // 已经存在这样的区间 68 continue; 69 } else { // 需要进行更新 70 if (prev->r + 1 == t) { // 可以和左侧合并 71 nxt.l = prev->l; 72 st.erase(prev); 73 } 74 } 75 } 76 if (next != st.end()) { 77 if (next->l == t + 1) { // 可以和右侧合并 78 nxt.r = next->r; 79 st.erase(next); 80 } 81 } 82 st.emplace(nxt); 83 84 } else if (query[i].first == 2) { 85 // 是否被包含? 86 auto next = st.upper_bound({t, 0}); 87 if (next != st.begin()) { 88 auto prev = next; 89 prev--; 90 if (prev->l <= t && t <= prev->r) { // 已经存在包含它的区间 91 int ans = prev->r + 1; 92 printf("%d\n", ans == n + 1 ? -1 : ans); // 输出答案 93 } else { 94 printf("%d\n", t); // 不存在包含它的区间,答案是自身 95 } 96 } else { // 没有找到,不被包含 97 printf("%d\n", t); 98 } 99 100 } 101 } 102 return 0; 103 }
C:
签到,出题人工地英语,原题是Codeforces 4A。
1 #include2 3 using namespace std; 4 5 int main() 6 { 7 int n; 8 cin >> n; 9 if(n >= 4&&n % 2 == 0){ 10 cout << "YES" <<endl; 11 }else { 12 cout << "NO" << endl; 13 } 14 15 return 0; 16 }
D:
因为数据范围很小,就变成了1000次KMP的无脑题。
1 #include2 3 using namespace std; 4 const int maxn = 200000; 5 6 void getFail(char* p,int* nxt) 7 { 8 int m = strlen(p); 9 nxt[0] = 0;nxt[1] = 0; 10 for(int i = 1;i < m;i++){ 11 int j = nxt[i]; 12 while(j && p[i] != p[j]) j = nxt[j]; 13 nxt[i+1] = p[i] == p[j] ? j + 1:0; 14 } 15 } 16 17 bool find(char* T,char* P,int *f){ 18 int n = strlen(T),m = strlen(P); 19 getFail(P,f); 20 int j = 0; 21 for(int i = 0;i < n;i++){ 22 while(j && P[j] != T[i]) j = f[j]; 23 if(P[j] == T[i]) j++; 24 if(j == m){ 25 return true; 26 } 27 } 28 return false; 29 } 30 int nxt[maxn]; 31 void init(int n) 32 { 33 for(int i =0;i <= n;i++){ 34 nxt[i] = 0; 35 } 36 } 37 38 39 int main() 40 { 41 char T[maxn]; 42 scanf("%s",T); 43 int n; 44 scanf("%d",&n); 45 for(int i = 1;i <= n;i++){ 46 char s[maxn]; 47 scanf("%s",s); 48 int len1= strlen(T); 49 int len2 = strlen(s); 50 init(max(len1,len2)); 51 if(len1 > len2){ 52 if(find(T,s,nxt)){ 53 printf("my child!\n"); 54 }else { 55 printf("oh, child!\n"); 56 } 57 }else if(len1 == len2){ 58 if(find(T,s,nxt)){ 59 printf("jntm!\n"); 60 }else { 61 printf("friend!\n"); 62 } 63 }else{ 64 if(find(s,T,nxt)){ 65 printf("my teacher!\n"); 66 }else { 67 printf("senior!\n"); 68 } 69 } 70 } 71 return 0; 72 }
E:
把数组元素和下标绑定后按数组元素值升序排序,对于每一个元素a[i],答案就是区间[i+1,n]里元素对应下标的最大值。线段树即可。
1 /* basic header */ 2 #include3 /* define */ 4 #define ll long long 5 #define pb emplace_back 6 #define mp make_pair 7 #define lson (curpos<<1) 8 #define rson (curpos<<1|1) 9 /* namespace */ 10 using namespace std; 11 /* header end */ 12 13 int read(void) { 14 char ch; 15 do { 16 ch = getchar(); 17 } while (!isdigit(ch)); 18 int ret = 0; 19 while (isdigit(ch)) { 20 ret *= 10; 21 ret += ch - '0'; 22 ch = getchar(); 23 }; 24 return ret; 25 } 26 27 const int maxn = 5e5 + 10; 28 struct Node { 29 int maxn; 30 } segt[maxn << 2]; 31 32 int n, m, ans[maxn]; 33 pair<int, int> a[maxn]; 34 35 void maintain(int curpos) { 36 segt[curpos].maxn = max(segt[lson].maxn, segt[rson].maxn); 37 } 38 39 void build(int curpos, int curl, int curr) { 40 if (curl == curr) { 41 segt[curpos].maxn = a[curl].second; 42 return; 43 } 44 int mid = curl + curr >> 1; 45 build(lson, curl, mid); build(rson, mid + 1, curr); 46 maintain(curpos); 47 } 48 49 int query(int curpos, int curl, int curr, int ql, int qr) { 50 if (ql <= curl && curr <= qr) { 51 return segt[curpos].maxn; 52 } 53 int mid = curl + curr >> 1, ret = -1; 54 if (ql <= mid) ret = max(ret, query(lson, curl, mid, ql, qr)); 55 if (mid < qr) ret = max(ret, query(rson, mid + 1, curr, ql, qr)); 56 return ret; 57 } 58 59 int main() { 60 n = read(), m = read(); 61 for (int i = 1; i <= n; i++) { 62 a[i].first = read(); 63 a[i].second = i; 64 } 65 sort(a + 1, a + 1 + n); 66 build(1, 1, n); 67 for (int i = 1; i <= n; i++) { 68 if (i == n) { 69 ans[a[i].second] = -1; 70 break; 71 } 72 int queryL = lower_bound(a + 1, a + 1 + n, mp(a[i].first + m, 0)) - (a + 1) + 1; 73 int maxPos = query(1, 1, n, queryL, n); 74 if (maxPos > a[i].second) ans[a[i].second] = maxPos - a[i].second - 1; 75 else ans[a[i].second] = -1; 76 } 77 for (int i = 1; i < n; i++) printf("%d ", ans[i]); 78 printf("%d\n", ans[n]); 79 return 0; 80 }
G:
Manacher魔改一下就能过的题。待补。
K:
O(n^2logn)暴力贪心。
1 #include2 3 using namespace std; 4 5 const int maxn = 200000; 6 7 const double eps = 1e-3; 8 bool dcmp(double x,double y) 9 { 10 if(abs(x - y) < eps){ 11 return true; 12 }else { 13 return false; 14 } 15 } 16 struct Point{ 17 double x,y; 18 bool operator == (Point rhs)const{ 19 return (dcmp(x,rhs.x) && dcmp(y,rhs.y)); 20 } 21 bool operator < (Point rhs)const{ 22 if(dcmp(x,rhs.x)){ 23 return y < rhs.y; 24 }else { 25 return x < rhs.x; 26 } 27 } 28 }P[maxn]; 29 vector vec; 30 set S; 31 bool CMP(Point p1,Point p2) 32 { 33 if(dcmp(p1.x,p2.x)){ 34 return p1.y < p2.y; 35 }else { 36 return p1.x < p2.x; 37 } 38 } 39 int main() 40 { 41 int n; 42 cin >> n; 43 for(int i = 1;i <= n;i++){ 44 cin >> P[i].x >> P[i].y; 45 } 46 if(n == 1 || n == 2){ 47 cout << 0 << endl; 48 return 0; 49 } 50 for(int i = 1;i <= n;i++){ 51 for(int j = 1;j <= n;j++){ 52 if(i == j) continue; 53 Point val; 54 val.x = P[i].x + P[j].x; 55 val.y = P[i].y + P[j].y; 56 val.x /= 2.0; 57 val.y /= 2.0; 58 vec.push_back(val); 59 } 60 } 61 for(int i = 1;i <= n;i++){ 62 vec.push_back(P[i]); 63 } 64 sort(vec.begin(),vec.end(),CMP); 65 int mx = 0; 66 int tot = 1; 67 Point pos; 68 for(int i = 1;i < vec.size();i++){ 69 if(mx < tot){ 70 mx = tot; 71 pos.x = vec[i].x; 72 pos.y = vec[i].y; 73 } 74 if(vec[i] == vec[i-1]){ 75 tot++; 76 }else { 77 tot = 1; 78 } 79 if(mx < tot){ 80 mx = tot; 81 pos.x = vec[i].x; 82 pos.y = vec[i].y; 83 } 84 } 85 for(int i = 1;i <= n;i++){ 86 S.insert(P[i]); 87 } 88 int ans = 0; 89 for(int i = 1;i <= n;i++){ 90 Point Sym; 91 Sym.x = pos.x + (pos.x - P[i].x); 92 Sym.y = pos.y + (pos.y - P[i].y); 93 if(!S.count(Sym)){ 94 ans ++ ; 95 } 96 } 97 cout << ans << endl; 98 return 0; 99 }
M:
队友说的记录26个字母位置乱搞完事(好像很真)。
1 /* Contest xuzhou_2019_online 2 * Problem M 3 * Team: Make One For Us 4 */ 5 #include6 7 using namespace std; 8 9 int main(void) { 10 ios::sync_with_stdio(false); 11 cin.tie(nullptr); 12 int n, m; 13 string a, b; 14 vector <int> pos[26]; 15 cin >> n >> m; 16 cin >> a >> b; 17 int ptr = 0; 18 // record position of each letter 19 for (unsigned int i = 0; i < a.length(); i++) { 20 pos[a[i] - 'a'].emplace_back(i); 21 } 22 int ans = -1; 23 // for each letter in target string 24 for (unsigned int i = 0; i < b.length(); i++) { 25 int cur = b[i] - 'a'; 26 // try to find the same letter (cur) 27 auto self = lower_bound(pos[cur].begin(), pos[cur].end(), ptr); 28 for (int nxt = cur + 1; nxt < 26; nxt++) { 29 auto upgrade = lower_bound(pos[nxt].begin(), pos[nxt].end(), ptr); 30 if (upgrade != pos[nxt].end()) { 31 auto p = *upgrade; 32 ans = max(ans, (int) (i + a.length() - p)); 33 } 34 } 35 if (self != pos[cur].end()) { 36 // found the letter, continue 37 ptr = *self + 1; // take *self, go on 38 if (i + 1 == b.length()) { 39 ans = max(ans, (int) (i + a.length() - ptr + 1)); 40 if (ans == b.length()) { 41 ans = -1; 42 } 43 } 44 } else { 45 // not found 46 break; 47 } 48 } 49 cout << ans << endl; 50 return 0; 51 } 52 53 // [abcd] 54 // 0123