20160916测试

这一次 3 道题都与 gcd 有关的测试,也是醉了……

T1

此题 5 分钟以内想出标算,然后 zz 地写挂,而且还能 TLE 掉…只拿了50…… 然而据 lcr 所说,此题最难!!!
思路与 gcd 相同,只是每次取 $\lfloor \frac m n \rfloor * n$ 个 $n$,然后令 $n_1 = m % n, m_1 = n$ 递归获迭代下去即可…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>
using namespace std;
inline int gcd(int x, int y) {
register int i, j;
if (!x) return y;
if (!y) return x;
for (i = 0; 0 == (x & 1); ++i) x >>= 1;
for (j = 0; 0 == (y & 1); ++j) y >>= 1;
if (j < i) i = j;
while (true) {
if (x < y) x ^= y ^= x ^= y;
if (!(x -= y)) return y << i;
while (!(x & 1)) x >>= 1;
}
}
#define solve(n, m) {\
register int tmp;\
while (m) {\
tmp = n / m * m;\
for (register int i = 1; i <= tmp; i++)\
cout << m << " ";\
n ^= m ^= n ^= m, m %= n;\
}\
}

int n, m, t;
int main() {
freopen("candy.in", "r", stdin);
freopen("candy.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m >> t;
if (n > m) n ^= m ^= n ^= m;
cout << n + m - gcd(n, m) << "\n";
if (!t) exit(0);
solve(m, n);
return 0;
}

T2

此题推了 2 个小时,但还是写挂了……
此题思路是令 d 为 gcd(K,连通分量中所有边权),则 ans 一定为 d 的倍数,最小就一定是 0 或 d,如果这个连通分量不是二分图,则存在奇环,ans 为 0;如果是二分图,则 x, y 同色为 0,染色后用并查集判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#pragma comment(linker, "/STACK:16777216")
#include <bits/stdc++.h>
using namespace std;
#define IO_SIZE 1048576
char buf[IO_SIZE], *S, *T, IO_c, IO_signum;
inline char read() {
if (S == T) {
T = (S = buf) + fread(buf, 1, IO_SIZE, stdin);
if (S == T) return EOF;
}
return *S++;
}
inline bool read(int& x) {
IO_signum = false;
for (IO_c = read(); IO_c < '0' || IO_c > '9'; IO_c = read()) {
if (IO_c == -1) return false;
if (IO_c == '-') IO_signum = true;
}
x = 0;
while (IO_c == 0) IO_c = read();
for (;; IO_c = read()) {
if (IO_c < '0' || IO_c > '9') break;
x = (x << 3) + (x << 1) + (IO_c ^ '0');
}
}
#define in(x, y) read(x), read(y)
int n, m, q;
struct node {
int to, next, w;
} edge[100010];
int disJointRank[50010], father[50010];
#define makeSet(x) disJointRank[x] = 0, father[x] = x;
inline int getFather(int x) {
register int px = x, i;
while (px ^ father[px]) px = father[px];
while (x ^ px) i = father[x], father[x] = px, x = i;
return px;
}
inline void unionSet(int x, int y) {
x = getFather(x), y = getFather(y);
if (disJointRank[x] > disJointRank[y])
father[y] = x;
else {
father[x] = y;
if (disJointRank[x] == disJointRank[y]) disJointRank[y]++;
}
}
inline int gcd(int x, int y) {
register int i, j;
if (!x) return y;
if (!y) return x;
for (i = 0; 0 == (x & 1); ++i) x >>= 1;
for (j = 0; 0 == (y & 1); ++j) y >>= 1;
if (j < i) i = j;
while (true) {
if (x < y) x ^= y ^= x ^= y;
if (!(x -= y)) return y << i;
while (!(x & 1)) x >>= 1;
}
}
#define insert(u, v, w) \
edge[++size].to = v, edge[size].w = w, edge[size].next = first[u], \
first[u] = size
int ans[50010], first[50010], size, color[50010];
bool vis[50010], flag;
inline void dfs1(int now) {
color[now] = -1;
for (register int u = first[now]; u; u = edge[u].next) {
ans[father[now]] = gcd(ans[father[now]], edge[u].w);
if (color[edge[u].to] ^ -1) dfs1(edge[u].to);
}
}
inline void dfs2(int now) {
vis[now] = true;
for (register int u = first[now]; u; u = edge[u].next) {
ans[father[now]] = gcd(ans[father[now]], edge[u].w);
if (!vis[edge[u].to]) dfs2(edge[u].to);
}
}
inline void dfs(int now, int column = 1) {
color[now] = column;
for (register int u = first[now]; u; u = edge[u].next) {
if (color[edge[u].to]) {
if ((edge[u].w / ans[father[now]]) & 1) {
if (color[edge[u].to] == color[now]) {
flag = true;
return;
}
} else {
if (color[edge[u].to] ^ color[now]) {
flag = true;
return;
}
}
} else {
if ((edge[u].w / ans[father[now]]) & 1)
dfs(edge[u].to, (((column - 1) ^ 1) + 1));
else
dfs(edge[u].to, column);
if (flag) return;
}
}
}
int main() {
freopen("pod.in", "r", stdin);
freopen("pod.out", "w", stdout);
in(n, m), read(q);
for (register int i = 1; i <= n; ++i) father[i] = i;
for (register int i = 1, u, v, w; i <= m; ++i)
in(u, v), read(w), insert(u, v, w), insert(v, u, w), unionSet(u, v);
for (register int i = 1; i <= n; ++i) getFather(i);
for (register int i = 1; i <= n; ++i)
if (father[i] == i) ans[i] = edge[first[i]].w;
for (register int i = 1; i <= n; ++i) {
if (!color[i]) dfs2(i), dfs(i);
if (flag) dfs1(i), flag = false;
}
for (register int i = 1, u, v, w; i <= q; ++i) {
in(u, v), read(w);
if (getFather(u) ^ getFather(v)) {
cout << "NIE\n";
continue;
}
if ((w / gcd(w, ans[father[u]]) & 1) || (color[u] == color[v])) {
cout << "0\n";
continue;
} else
cout << gcd(w, ans[father[u]]) << "\n";
}
return 0;
}

T3

此题想出正解了,然而没时间写完了,论T2的耗时……
此题可以神奇地维护前缀和,实现近乎 $O(n)$ 级别的算法。
此题也可用线段树,复杂度 $O(n+q \log n)$,你们不觉得线段树常数大吗?
然而我还是直接来了个最暴力的,莫队算法,这个题直接莫队暴力转移 g, c, d, gc, cd, gcd 就好,虽说复杂度 $O(n^{1.5})$,但事实证明莫队比线段树快多了……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <bits/stdc++.h>
using namespace std;
#define IO_SIZE 2048576
char buf[IO_SIZE], *S, *T, IO_c, IO_signum;
inline char read() {
if (S == T) {
T = (S = buf) + fread(buf, 1, IO_SIZE, stdin);
if (S == T) return EOF;
}
return *S++;
}
inline bool read(int& x) {
IO_signum = false;
for (IO_c = read(); IO_c < '0' || IO_c > '9'; IO_c = read()) {
if (IO_c == -1) return false;
if (IO_c == '-') IO_signum = true;
}
x = 0;
while (IO_c == 0) IO_c = read();
for (;; IO_c = read()) {
if (IO_c < '0' || IO_c > '9') break;
x = (x << 3) + (x << 1) + (IO_c ^ '0');
}
}
int len;
inline void read(char* s) {
register char ch = read();
while (ch != 'r' && ch != '\n') *s++ = ch, ch = read(), ++len;
}
#define in(x, y) read(x), read(y)
const unsigned int mod = 1 << 31;
typedef unsigned int ui;
char s[80010];
int q, l, r, block;
ui g, c, d, gc, cd, gcd;
struct query {
int l, r, pos, num, ans;
inline bool operator<(const query& a) const { return num < a.num; }
} que[80010];
inline bool cmp(const query& a, const query& b) {
if (a.pos ^ b.pos) return a.pos < b.pos;
return a.r < b.r;
}
#define init() \
read(s + 1), read(q); \
block = sqrt(len); \
for (register int i = 1; i <= q; ++i) \
in(que[i].l, que[i].r), que[i].num = i, \
que[i].pos = (que[i].l - 1) / block + 1; \
sort(que + 1, que + q + 1, cmp);

inline void getGCD(int l) {
switch (s[l]) {
case 'g':
++g;
break;
case 'c':
++c;
break;
case 'd':
++d;
break;
}
}
inline void rr() {
++r;
switch (s[r]) {
case 'g':
g = (g + 1) % mod;
break;
case 'c':
c = (c + 1) % mod, gc = (gc + g) % mod;
break;
case 'd':
d = (d + 1) % mod, gcd = (gcd + gc) % mod, cd = (cd + c) % mod;
break;
}
}
inline void ll() {
--l;
switch (s[l]) {
case 'g':
g = (g + 1) % mod, gcd = (gcd + cd) % mod, gc = (gc + c) % mod;
break;
case 'c':
c = (c + 1) % mod, cd = (cd + d) % mod;
break;
case 'd':
d = (d + 1) % mod;
break;
}
}
inline void lr() {
switch (s[l]) {
case 'g':
g = (g - 1 + mod) % mod, gcd = (gcd - cd + mod) % mod,
gc = (gc - c + mod) % mod;
break;
case 'c':
c = (c - 1 + mod) % mod, cd = (cd - d + mod) % mod;
break;
case 'd':
d = (d - 1 + mod) % mod;
break;
}
++l;
}
inline void moQuery() {
init();
for (register int i = 1; i <= q; ++i) {
if (que[i].pos ^ que[i - 1].pos) {
g = c = d = cd = gc = gcd = 0, l = r = que[i].l, getGCD(l);
while (r < que[i].r) rr();
que[i].ans = gcd;
} else {
while (r < que[i].r) rr();
while (l > que[i].l) ll();
while (l < que[i].l) lr();
que[i].ans = gcd;
}
}
sort(que + 1, que + q + 1);
for (int i = 1; i <= q; i++) cout << que[i].ans << "\n";
}
int main() {
freopen("gcd.in", "r", stdin);
freopen("gcd.out", "w", stdout);
moQuery();
return 0;
}

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×