A. Parity
签.

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define N 100010
5 int b, k, a[N];
6
7 int main()
8 {
9 while (scanf("%d%d", &b, &k) != EOF)
10 {
11 int res = 0;
12 for (int i = 1; i <= k; ++i) scanf("%d", a + i);
13 int base = 1;
14 for (int i = k; i >= 1; --i)
15 {
16 res = (res + a[i] * base % 2) % 2;
17 base = base * b % 2;
18 }
19 puts(res % 2 ? "odd" : "even");
20 }
21 return 0;
22 }
做的时候卡了一会儿
因为想用费马小定理
认为
$b^x = b^{(x \% \phi(m))} \pmod m$
然后幂次都变为$0$
就直接加起来$模2判断一下就好了$
$但是没有考虑到0^0次的问题$
$在这里如果b \% 2 == 0, 那么带b的项都为0$

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define N 100010
5 int b, k, a[N];
6
7 int main()
8 {
9 while (scanf("%d%d", &b, &k) != EOF)
10 {
11 int res = 0;
12 for (int i = 1; i <= k; ++i) scanf("%d", a + i);
13 for (int i = 1; i <= k; ++i)
14 res = (res + a[i] % 2) % 2;
15 if (b % 2 == 0) res = a[k];
16 puts(res % 2 ? "odd" : "even");
17 }
18 return 0;
19 }
B. Tape
签.

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define N 100010
5 int n, m, k;
6 int b[N];
7
8 int main()
9 {
10 while (scanf("%d%d%d", &n, &m, &k) != EOF)
11 {
12 --k;
13 for (int i = 1; i <= n; ++i) scanf("%d", b + i);
14 int res = b[n] - b[1] + 1;
15 priority_queue <int> pq;
16 for (int i = 2; i <= n; ++i) pq.push(b[i] - b[i - 1] - 1);
17 while (!pq.empty() && k--)
18 {
19 res -= pq.top();
20 pq.pop();
21 }
22 printf("%d\n", res);
23 }
24 return 0;
25 }
C. Meaningless Operations
Solved.
题意:
给出一个数$a$
$定义(f(a) = max_{1 <= b < a} gcd(a \oplus b, a \& b))$
给出$f(a)$
思路:
考虑$gcd(x, 0) = x$
那么我们构造$(a \& b) = 0, 并且 (a \oplus b)最大即可$
$对于2^x - 1 这种东西是没法构造的$
$考虑这样的数不多,提前打表即可$

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 int q, x;
5 map <int, int> ans;
6
7 int solve(int x)
8 {
9 if (ans.find(x) != ans.end()) return ans[x];
10 int res;
11 for (int i = 24; i >= 0; --i) if (((x >> i) & 1))
12 {
13 res = (1 << (i + 1)) - 1;
14 break;
15 }
16 return ans[x] = res;
17 }
18
19 int main()
20 {
21 ans[1] = 1,
22 ans[3] = 1,
23 ans[7] = 1,
24 ans[15] = 5,
25 ans[31] = 1,
26 ans[63] = 21,
27 ans[127] = 1,
28 ans[255] = 85,
29 ans[511] = 73,
30 ans[1023] = 341,
31 ans[2047] = 89,
32 ans[4095] = 1365,
33 ans[8191] = 1,
34 ans[16383] = 5461,
35 ans[32767] = 4681,
36 ans[65535] = 21845,
37 ans[131071] = 1,
38 ans[262143] = 87381,
39 ans[524287] = 1,
40 ans[1048575] = 349525,
41 ans[2097151] = 299593,
42 ans[4194303] = 1398101,
43 ans[8388607] = 178481,
44 ans[16777215] = 5592405,
45 ans[33554431] = 1082401;
46 while (scanf("%d", &q) != EOF)
47 {
48 while (q--)
49 {
50 scanf("%d", &x);
51 printf("%d\n", solve(x));
52 }
53 }
54 return 0;
55 }
D. Jongmah
Upsolved.
题意:
有一些数字,三个相同的数字消去
三个连续的也可以消去
求最多消去多少组
思路:
$dp[i][j][k] 表示到第i大的数, 第i - 2大的数还余了j个, 第i - 1个数还余了k个$
$的最大消去的组数$
$转移的时候注意能跟前面的余数组成连续的就组成连续的$
$因为和前面余数组成连续的只需要出一张牌就获得1的贡献$
$如果消去当前三张相同的需要三张牌,至少是不会亏的$
$注意转移的时候要把前面的余数也剪掉$
$再考虑每张牌最多出5张和前面和后面的其他牌组成连续的$
$那么j, k的状态只有6个$

1 #include <bits/stdc++.h>
2 using namespace std;
3
4
5 #define ll long long
6 #define N 1000010
7 int n, m, a[N];
8 ll f[2][6][6];
9
10 int main()
11 {
12 while (scanf("%d%d", &n, &m) != EOF)
13 {
14 memset(a, 0, sizeof a);
15 memset(f, -1, sizeof f);
16 for (int i = 1, x; i <= n; ++i)
17 {
18 scanf("%d", &x);
19 ++a[x];
20 }
21 if (m <= 2)
22 {
23 printf("%d\n", a[1] / 3 + a[2] / 3);
24 continue;
25 }
26 ll res = 0;
27 for (int i = 0; i < 6; ++i)
28 for (int j = 0; j < 6; ++j)
29 if (a[1] >= i && a[2] >= j)
30 f[2 & 1][i][j] = (a[1] - i) / 3 + (a[2] - j) / 3;
31 //for (int i = 1; i <= m; ++i) printf("%d%c", a[i], " \n"[i == m]);
32 for (int i = 3; i <= m; ++i)
33 {
34 for (int j = 0; j < 6; ++j)
35 for (int k = 0; k < 6; ++k)
36 f[i & 1][j][k] = -1;
37 for (int j = 0; j < 6; ++j)
38 {
39 for (int k = 0; k < 6; ++k) if (f[(i & 1) ^ 1][j][k] != -1)
40 {
41 for (int o = 0; o < 6; ++o)
42 {
43 int need = min(j, min(a[i] - o, k));
44 ll base = f[(i & 1) ^ 1][j][k];
45 if (a[i] >= o)
46 f[i & 1][k - need][o] = max(f[i & 1][k - need][o], base + (a[i] - o - need) / 3 + need);
47 }
48 }
49 }
50 //for (int j = 0; j < 3; ++j)
51 // for (int k = 0; k < 3; ++k)
52 // printf("%d %d %d %lld\n", i, j, k, f[i][j][k]);
53 }
54 for (int i = 0; i < 6; ++i)
55 for (int j = 0; j < 6; ++j)
56 res = max(res, f[m & 1][i][j]);
57 printf("%lld\n", res);
58 }
59 return 0;
60 }
E. Magic Stones
Upsolved.
题意:
有一个数字序列$A[], 每次可以选择一个i \in [2, n - 1]$
$使得 A[i] = A[i + 1] + A[i - 1] - A[i]$
问能否经过一些这样的操作,使得$A[] -> B[]$
思路:
我们令$d[i] = A[i + 1] - A[i]$
我们考虑$上述的那个操作$
$d_i = A[i + 1] - (A[i + 1] + A[i - 1] - A[i]) = A[i] - A[i - 1] = d_{i - 1}$
同理
$d_{i - 1} = d_{i}$
我们注意到,这个操作变成了交换元素
$那么把B[]数组也变成差分数组,如果两个差分数组通过任意交换后相同$
$那么原序列通过以系列操作也可以相同$
$即排个序判断是否相同即可,再注意一下第一个是否相同$

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define N 100010
5 int n, c[N], t[N];
6 int a[N], b[N];
7
8 bool ok()
9 {
10 for (int i = 1; i < n; ++i)
11 if (a[i] != b[i])
12 return false;
13 return true;
14 }
15
16 int main()
17 {
18 while (scanf("%d", &n) != EOF)
19 {
20 for (int i = 1; i <= n; ++i)
21 {
22 scanf("%d", c + i);
23 if (i > 1)
24 a[i - 1] = c[i] - c[i - 1];
25 }
26 for (int i = 1; i <= n; ++i)
27 {
28 scanf("%d", t + i);
29 if (i > 1)
30 b[i - 1] = t[i] - t[i - 1];
31 }
32 sort(a + 1, a + n);
33 sort(b + 1, b + n);
34 puts(ok() && c[1] == t[1] ? "Yes" : "No");
35 }
36 return 0;
37 }
F. Nearest Leaf
Upsolved.
题意:
给出一个树, 询问$离v节点最近叶子节点的距离$
注意给出的点序是$DFS序$
思路:
将询问离线,令根为$1$
$考虑如果询问1号点,那么跑一遍DFS,将所有点的距离丢进线段树$
$查最小值即可$
那么对于一个点$x$
我们考虑从线段树里面维护的距离是到它父亲$y的距离$
$那么我们要把这个距离转变成到x的距离$
$可以发现,它子树内的点都需要减去一条边,就是它父亲到它那条边$
$它子树外的点都需要加上一条边,是它父亲到它那条边$
$子树内的点是连续的,所以可以在线段树上操作$

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define ll long long
5 #define N 500010
6 int n, q;
7 struct qnode
8 {
9 int l, r, id;
10 qnode () {}
11 qnode (int l, int r, int id) : l(l), r(r), id(id) {}
12 };
13 vector <qnode> vec[N];
14 ll ans[N];
15 struct Graph
16 {
17 struct node
18 {
19 int to, nx, w;
20 node () {}
21 node (int to, int nx, int w) : to(to), nx(nx), w(w) {}
22 }a[N << 1];
23 int head[N], pos;
24 void init()
25 {
26 memset(head, 0, sizeof head);
27 pos = 0;
28 }
29 void add(int u, int v, int w)
30 {
31 a[++pos] = node(v, head[u], w); head[u] = pos;
32 a[++pos] = node(u, head[v], w); head[v] = pos;
33 }
34 }G;
35 #define erp(u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w; it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w)
36 int fa[N], isleaf[N]; ll dis[N];
37
38 namespace SEG
39 {
40 ll Min[N << 2], lazy[N << 2];
41 void pushup(int id) { Min[id] = min(Min[id << 1], Min[id << 1 | 1]); }
42 void build(int id, int l, int r)
43 {
44 lazy[id] = 0;
45 if (l == r)
46 {
47 Min[id] = dis[l];
48 if (!isleaf[l]) Min[id] = (ll)1e18;
49 return;
50 }
51 int mid = (l + r) >> 1;
52 build(id << 1, l, mid);
53 build(id << 1 | 1, mid + 1, r);
54 pushup(id);
55 }
56 void pushdown(int id)
57 {
58 if (!lazy[id]) return;
59 lazy[id << 1] += lazy[id];
60 lazy[id << 1 | 1] += lazy[id];
61 Min[id << 1] += lazy[id];
62 Min[id << 1 | 1] += lazy[id];
63 lazy[id] = 0;
64 }
65 void update(int id, int l, int r, int ql, int qr, ll val)
66 {
67 if (l >= ql && r <= qr)
68 {
69 Min[id] += val;
70 lazy[id] += val;
71 return;
72 }
73 pushdown(id);
74 int mid = (l + r) >> 1;
75 if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
76 if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
77 pushup(id);
78 }
79 ll query(int id, int l, int r, int ql, int qr)
80 {
81 if (l >= ql && r <= qr) return Min[id];
82 pushdown(id);
83 int mid = (l + r) >> 1;
84 ll res = (ll)1e18;
85 if (ql <= mid) res = min(res, query(id << 1, l, mid, ql, qr));
86 if (qr > mid) res = min(res, query(id << 1 | 1, mid + 1, r, ql, qr));
87 return res;
88 }
89 }
90
91 int lp[N], rp[N];
92 void DFS1(int u)
93 {
94 lp[u] = u;
95 rp[u] = u;
96 erp(u) if (v != fa[u])
97 {
98 fa[v] = u;
99 dis[v] = dis[u] + w;
100 DFS1(v);
101 rp[u] = max(rp[u], rp[v]);
102 }
103 isleaf[u] = (lp[u] == rp[u]);
104 }
105
106 void DFS2(int u)
107 {
108 for (auto it : vec[u])
109 ans[it.id] = SEG::query(1, 1, n, it.l, it.r);
110 erp(u) if (v != fa[u])
111 {
112 SEG::update(1, 1, n, 1, n, w);
113 SEG::update(1, 1, n, lp[v], rp[v], -2ll * w);
114 DFS2(v);
115 SEG::update(1, 1, n, 1, n, -w);
116 SEG::update(1, 1, n, lp[v], rp[v], 2ll * w);
117 }
118 }
119
120 int main()
121 {
122 while (scanf("%d%d", &n, &q) != EOF)
123 {
124 for (int i = 1; i <= n; ++i) vec[i].clear();
125 G.init();
126 for (int i = 2, p, w; i <= n; ++i)
127 {
128 scanf("%d%d", &p, &w);
129 G.add(i, p, w);
130 }
131 for (int i = 1, v, l, r; i <= q; ++i)
132 {
133 scanf("%d%d%d", &v, &l, &r);
134 vec[v].emplace_back(l, r, i);
135 }
136 dis[1] = 0;
137 DFS1(1);
138 SEG::build(1, 1, n);
139 DFS2(1);
140 for (int i = 1; i <= q; ++i) printf("%lld\n", ans[i]);
141 }
142 return 0;
143 }
来源:https://www.cnblogs.com/Dup4/p/10355916.html
