Codeforces Round 949 (Div. 2)

lyrrr發表於2024-09-10

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";
		}
	}
}

相關文章