A. Good ol' Numbers Coloring
Description
给出两个整数x,y,问$ax+by,a \geq 0,b \ geq 0$不能表示的正整数是否为无穷多个。
Solution
由裴属定理可以知道当$gcd(x,y)|m$时,等式$ax+by=m$一定存在整数解。
那么显然判断条件就是$gcd(x,y)==1$
B. Restricted RPS
Description
已知Bob的剪刀石头布序列。
Alice本人剪刀石头布的次数给定,$a+b+c=n$
Alice至少赢Bob$\lceil \frac{n}{2} \rceil$局才能获胜。
问Alice能否获胜,若可以,给出一组答案序列。
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 = 1e2 + 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], ans[maxn];
88 int vis[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;
96 cin >> t;
97 while (t--)
98 {
99 memset(vis, 0, sizeof vis);
100 cin >> n;
101 int a, b, c;
102 cin >> a >> b >> c;
103 cin >> s + 1;
104 int res = 0;
105 for (int i = 1; i <= n; i++)
106 if (s[i] == 'P' && c)
107 --c, ans[i] = 'S', ++res, vis[i] = 1;
108 else if (s[i] == 'S' && a)
109 --a, ans[i] = 'R', ++res, vis[i] = 1;
110 else if (s[i] == 'R' && b)
111 --b, ans[i] = 'P', ++res, vis[i] = 1;
112 int p = n / 2;
113 if (n & 1)
114 ++p;
115 if (res >= p)
116 {
117 cout << "YES\n";
118 for (int i = 1; i <= n; i++)
119 if (!vis[i])
120 {
121 if (a)
122 ans[i] = 'R',--a;
123 else if (b)
124 ans[i] = 'P',--b;
125 else if (c)
126 ans[i] = 'S',--c;
127 vis[i] = 1;
128 }
129 ans[n + 1] = '\0';
130 cout << ans + 1 << "\n";
131 }
132 else
133 cout << "NO\n";
134 }
135 return 0;
136 }
C. Constanze's Machine

C发明了一个听声打字机器。
D恶作剧了一下,将机器修改为
如果C说的是$m$,机器输出$nn$
如果C说的是$w$,机器输出$uu$
A拿到了一串C的输出序列,问有多少种复原方案。
Solution
处理序列中连续的u和n,按照分步原则,将答案累乘。
中间规律为斐波那契。

1 #include <algorithm>
2 #include <numeric>
3 #include <cctype>
4 #include <cmath>
5 #include <cstdio>
6 #include <cstdlib>
7 #include <cstring>
8 #include <iostream>
9 #include <map>
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 const ll mod = 1e9 + 7;
32 template <class T>
33 inline T read()
34 {
35 int f = 1;
36 T ret = 0;
37 char ch = getchar();
38 while (!isdigit(ch))
39 {
40 if (ch == '-')
41 f = -1;
42 ch = getchar();
43 }
44 while (isdigit(ch))
45 {
46 ret = (ret << 1) + (ret << 3) + ch - '0';
47 ch = getchar();
48 }
49 ret *= f;
50 return ret;
51 }
52 template <class T>
53 inline void write(T n)
54 {
55 if (n < 0)
56 {
57 putchar('-');
58 n = -n;
59 }
60 if (n >= 10)
61 {
62 write(n / 10);
63 }
64 putchar(n % 10 + '0');
65 }
66 template <class T>
67 inline void writeln(const T &n)
68 {
69 write(n);
70 puts("");
71 }
72 template <typename T>
73 void _write(const T &t)
74 {
75 write(t);
76 }
77 template <typename T, typename... Args>
78 void _write(const T &t, Args... args)
79 {
80 write(t), pblank;
81 _write(args...);
82 }
83 template <typename T, typename... Args>
84 inline void write_line(const T &t, const Args &... data)
85 {
86 _write(t, data...);
87 }
88 char s[maxn];
89 ll dp[maxn];
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 dp[0] = 1, dp[1] = 1;
97 for (int i = 2; i < maxn;i++)
98 dp[i] = (dp[i - 1] + dp[i - 2]) % mod;
99 fastIO;
100 cin >> s;
101 n = strlen(s);
102 int f = 1;
103 for (int i = 0; i < n && f;i++)
104 if (s[i]=='m'||s[i]=='w')
105 f = 0;
106 if (f){
107 ll res = 1;
108 int cur = 0;
109 for (int i = 0; i < n;i++){
110 if (s[i]=='u')
111 ++cur;
112 else{
113 res = res * dp[cur] % mod;
114 cur = 0;
115 }
116 }
117 if (cur)
118 res = res * dp[cur] % mod;
119 cur = 0;
120 for (int i = 0; i < n; i++)
121 {
122 if (s[i] == 'n')
123 ++cur;
124 else
125 {
126 res = res * dp[cur] % mod;
127 cur = 0;
128 }
129 }
130 if (cur)
131 res = res * dp[cur] % mod;
132 cout << res << "\n";
133 }
134 else
135 puts("0");
136 return 0;
137 }
D. Shichikuji and Power Grid
Description
给出一个含有n个点的城市,以及各自坐标。
现在要将n个点全部连上主干道电路。
对于每个点有两种可选方案。
1,自己铺设电路到主干道。2,铺设电路到某一已连上主干道的点。
第一种方式的代价为$C_i$
第二种的代价为$(K_i+K_j) \times (dis_{i,j}),dis_{i,j}=|x_i-x_j|+|y_i-y_j|$
问最小代价,并给出铺设方案。
Solution
最小生成树。自己太菜没有及时想到做法。
思路源自题解。
对于第一个点,由于没有其他已连上主干道的点,它的选择只能是第一种方式。
这时其他点的代价可以更新为$min(c_i,dis_{i,u} \times (k_i+k_u))$。
prim可在$O(n^2)$内求出答案。

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 ll dis(const P &t1, const P &t2)
89 {
90 return 1LL*abs(t1.first - t2.first) + abs(t1.second - t2.second);
91 }
92 int main(int argc, char const *argv[])
93 {
94 #ifndef ONLINE_JUDGE
95 freopen("in.txt", "r", stdin);
96 // freopen("out.txt","w", stdout);
97 #endif
98 n = read<int>();
99 vector<P> vec(n + 1), con;
100 vector<int> c(n + 1), k(n + 1), fa(n + 1, -1), vis(n + 1, 0), self;
101 for (int i = 1; i <= n; i++)
102 {
103 int x = read<int>(), y = read<int>();
104 vec[i] = P(x, y);
105 }
106 for (int i = 1; i <= n; i++)
107 c[i] = read<int>();
108 for (int i = 1; i <= n; i++)
109 k[i] = read<int>();
110 ll res = 0;
111 for (int i = 1; i <= n; i++)
112 {
113 int u = -1, minx = 2e9;
114 for (int j = 1; j <= n; j++)
115 if (c[j] < minx && !vis[j])
116 {
117 minx = c[j];
118 u = j;
119 }
120 if (u != -1)
121 vis[u] = 1, res += minx;
122 else
123 break;
124 if (fa[u] != -1)
125 con.emplace_back(fa[u], u);
126 else
127 self.emplace_back(u);
128 for (int j = 1; j <= n; j++)
129 {
130 if (j == u || vis[j])
131 continue;
132 ll d = 1LL * dis(vec[u], vec[j]) * (k[u] + k[j]);
133 if (d < c[j])
134 c[j] = d, fa[j] = u;
135 }
136 }
137 writeln(res);
138 int sz = self.size();
139 writeln(sz);
140 for (int i = 0; i < sz; i++)
141 write(self[i]), pblank;
142 puts("");
143 sz = con.size();
144 writeln(sz);
145 for (int i = 0; i < sz; i++)
146 write_line(con[i].first, con[i].second);
147 return 0;
148 }
F据说是牛客多校原题。
