B. Turtle and an Infinite Sequence
看到位運算就應該按位考慮的,我想的是按數擴散沒想按位擴散最後就大錯特錯了。。
按位擴散主要是得想到每個p2[i]每隔p2[i]次就會出現一遍。。如果能擴散到就存在。
#include<bits/stdc++.h>
#define ls(x) (x<<1)
#define rs(x) ((x<<1)|1)
#define mid ((l+r)>>1)
#define pb push_back
#define int long long
using namespace std;
const int maxn = 5e5 + 10;
int id[maxn], a[maxn], k, b[maxn];
int p2[100],lca;
signed main() {
p2[0] = 1; for (int i = 1; i <= 33; i++)p2[i] = p2[i - 1] * 2;
int tt; cin >> tt; while (tt--) {
int n,m; cin >> n >> m;
int ans = 0;
for(int i=32;i>=0;i--){
int x = n % p2[i];
if (n & p2[i]) {
ans += p2[i];
}
else if (n < p2[i]) {
if (p2[i] - x <= m)ans += p2[i];
}
else {
int tmp = min(p2[i] - x, x + 1);
if (tmp <= m)ans += p2[i];
}
}
cout << ans << "\n";
}
}
C - Turtle and an Incomplete Sequence
不知道算不算構造題,如果能發現相鄰的點其實就是要走二叉樹上的邊的話就很好做了,找lca最短路徑即可判斷是否能到
#include<bits/stdc++.h>
#define ls(x) (x<<1)
#define rs(x) ((x<<1)|1)
#define mid ((l+r)>>1)
#define pb push_back
#define int long long
using namespace std;
const int maxn = 5e5 + 10;
int id[maxn], a[maxn], k, b[maxn];
int p2[100],lca;
int LCA(int x, int y) {
int res = 0, depx=0, depy=0;
for (int i = 0; i <= 32;i++) {
if ((x / p2[i]) == 1) {
depx = i + 1;
break;
}
}
for (int i = 0; i <= 32; i++) {
if ((y / p2[i]) == 1) {
depy = i + 1;
break;
}
}
//cout << y << ' ' << x << "mk\n";
//cout << depy << ' ' << depx << "mk\n";
if (depy < depx)swap(x, y), swap(depx, depy);
int dep = depy - depx;
res += dep; y = y / p2[dep];
lca = x;
if (x == y)return res;
for (int i = 32; i >= 0; i--) {
if ((x>>i) != (y>>i)) {
x = (x>>i), y = (y>>i);
res += i*2;
}
//cout << res << "mk\n";
}
lca = x / 2;
return res+2;
}
signed main() {
p2[0] = 1; for (int i = 1; i <= 33; i++)p2[i] = p2[i - 1] * 2;
int tt; cin >> tt; while (tt--) {
int n; cin >> n; k = 0;
vector<int>vt;
for (int i = 1; i <= n; i++) {
int x; cin >> x;
if (x != -1)id[++k] = i, a[k] = x;
}
if (k == 0) {
for (int i = 1; i <= n; i++) {
if (i % 2)cout << 1 << ' ';
else cout << 2 << ' ';
}
cout << "\n";
continue;
}
bool x = 1;
for (int i = 1; i < k; i++) {
b[id[i]] = a[i];
int l = LCA(a[i], a[i + 1]);
//cout << l <<"mk\n";
if (l <= (id[i + 1] - id[i]) && (l % 2 == (id[i + 1] - id[i]) % 2)) {
int j = id[i] + 1, tmp = a[i]/2;
while (tmp > lca) {
b[j] = tmp; tmp /= 2; j++;
}
int r = id[i + 1]; tmp = a[i + 1];
while (tmp > lca) {
b[r] = tmp; tmp /= 2; r--;
}
int p = 1;
while (r >= j) {
if (p) b[r] = tmp;
else b[r] = tmp * 2;
r--; p ^= 1;
}
}
else {
x = 0; break;
}
}
if (!x)cout << -1 << "\n";
else {
int p = id[1] % 2;
for (int i = id[1]; i >= 1; i--) {
if (i % 2 == p)b[i] = a[1];
else b[i] = a[1] * 2;
}
p = id[k] % 2;
for (int i = id[k]; i <= n; i++) {
if (i % 2 == p)b[i] = a[k];
else b[i] = a[k] * 2;
}
for (int i = 1; i <= n; i++)cout << b[i] << ' ';
cout << "\n";
}
}
}