2019 ICPC XuZhou Regional Online Contest

比较水的一场。

题目链接: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 #include <bits/stdc++.h>
  6 
  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 <pair <int, int>> query(q);
 36     // vector <int> nums(2 * q + 1);
 37     set <range> st;
 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
", ans == n + 1 ? -1 : ans); // 输出答案
 93                 } else { 
 94                     printf("%d
", t); // 不存在包含它的区间,答案是自身
 95                 }
 96             } else { // 没有找到,不被包含
 97                 printf("%d
", t);
 98             }
 99 
100         }
101     }
102     return 0;
103 }
View Code

C:

签到,出题人工地英语,原题是Codeforces 4A。

 1 #include<bits/stdc++.h>
 2 
 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 }
View Code

D:

因为数据范围很小,就变成了1000次KMP的无脑题。

 1 #include<bits/stdc++.h>
 2 
 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!
");
54             }else {
55                 printf("oh, child!
");
56             }
57         }else if(len1 == len2){
58             if(find(T,s,nxt)){
59                 printf("jntm!
");
60             }else {
61                 printf("friend!
");
62             }
63         }else{
64             if(find(s,T,nxt)){
65                 printf("my teacher!
");
66             }else {
67                 printf("senior!
");
68             }
69         }
70     }
71     return 0;
72 }
View Code

E:

把数组元素和下标绑定后按数组元素值升序排序,对于每一个元素a[i],答案就是区间[i+1,n]里元素对应下标的最大值。线段树即可。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* 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
", ans[n]);
79     return 0;
80 }
View Code

G:

Manacher魔改一下就能过的题。待补。

K:

O(n^2logn)暴力贪心。

 1 #include<bits/stdc++.h>
 2 
 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<Point> vec;
30 set<Point> 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 }
View Code

M:

队友说的记录26个字母位置乱搞完事(好像很真)。

 1 /* Contest xuzhou_2019_online
 2  * Problem M
 3  * Team: Make One For Us
 4  */
 5 #include <bits/stdc++.h>
 6 
 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
View Code
原文地址:https://www.cnblogs.com/JHSeng/p/11490242.html