Codeforces Round 875 (Div. 2) A~D

Codeforces Round 875 (Div. 2) A~D

A. Twin Permutations

构造\(a[i]+b[i]=n+1\)

void work() {  
	int n;
	cin >> n;
	rep (i, 1, n) {
		int x;
		cin >> x;
		cout << n - x + 1 << " ";
	}
	cout << endl;
}

B. Array merging

对于最长的subarray,每个数组最多贡献一个连续段

void work() {  
	int n;
	cin >> n;
	vector<LL> a(n + 1), b(n + 1), cnta(2 * n + 1), cntb(2 * n + 1);
	LL res = 0, len = 0;	
	rep (i, 1, n) {
		cin >> a[i];
		if (a[i] != a[i - 1]) {
			cnta[a[i - 1]] = max(cnta[a[i - 1]], len);
			len = 1;
		}
		else len++;
	}
	if (len) cnta[a[n]] = max(cnta[a[n]], len);
	len = 0;
	rep (i, 1, n) {
		cin >> b[i];
		if (b[i] != b[i - 1]) {
			cntb[b[i - 1]] = max(cntb[b[i - 1]], len);
			len = 1;
		}
		else len++;
	}
	if (len) cntb[b[n]] = max(cntb[b[n]], len);
	rep (i, 1, 2 * n) {
		res = max(res, cnta[i] + cntb[i]);
	}
	cout << res << "\n";
}

C. Copil Copac Draws Trees

结点\(u\)能被选择,当且仅当其所有祖先结点都被选择。所以整个过程是由根不断向叶子扩展的过程,可以用\(dfs\)传入上一条边的\(id\),如果当前边的\(id\)小于它,就只能在下一个回合被选择,\(f[v]=f[u]+1\),否则\(f[v]=f[u]\),时间复杂度\(O(n)\)

void work() {  
	int n;
	cin >> n;
	
	vector<int> dp(n + 1);
	vector<vector<PII>> g(n + 1);
	
	rep (i, 1, n - 1) {
		int u, v;
		cin >> u >> v;
		g[u].push_back({v, i});
		g[v].push_back({u, i});
	}
	
	function<void(int, int, int)> dfs = [&](int u, int fa, int uid) {
		for (auto x: g[u]) {
			int v = x.fr, id = x.se;
			if (v == fa) continue;
			if (id < uid) dp[v] = dp[u] + 1;
			else dp[v] = dp[u];
			dfs(v, u, id);
		}
	};
	
	dfs(1, 0, 0);
	
	int res = 1;
	rep (i, 1, n) res = max(res, dp[i] + 1);
	cout << res << "\n";
}

D. The BOSS Can Count Pairs

对于\(a[i]*a[j]=b[i]+b[j]\)成立的所有\((i,j)\)\(b[i]+b[j]<=2*n\),所以\(min(a[i],a[j])<=sqrt(2*n)\)。外层枚举\(min(a[i],a[j])\)的值来统计。

赛时很快想到这里,但是内层循环居然去枚举\(a[i]*a[j]\),这样内层的时间复杂度远不止\(O(n)\),导致放弃了这个思路,其实遍历一遍数组就能统计了。

时间复杂度\(O(nsqrt(2n))\)

int f[N];
 
void work() {
    int n;
    cin >> n;
    vector<int> a(n + 1), b(n + 1);
    rep (i, 1, n) cin >> a[i];
    rep (i, 1, n) cin >> b[i];
    
    LL res = 0;
    for (int i = 1; i * i <= 2 * n; i++) {
        rep (j, 1, n) {
            if (a[j] == i) {
                if (b[j] < i * i) res += f[i * i - b[j]];
                f[b[j]]++;
            }
        }
        rep (j, 1, n) {
            if (a[j] > i && 1ll * a[j] * i <= 2 * n) {
                if (b[j] < a[j] * i) res += f[a[j] * i - b[j]];
            }
        }
        rep (j, 1, n) if (a[j] == i) f[b[j]]--;
    }
    
    cout << res << "\n";
}
posted @ 2023-05-29 09:34  xhy666  阅读(251)  评论(0)    收藏  举报