1 条题解

  • 0
    @ 2026-5-6 11:23:22

    由于只需要得到等价的图,所以只用求出所有的连通块信息。我们先求出 nn 个版本表示把前 ii 的点全部连通后的图,我们考察点 ii,如果版本 jj 是第一个使得 ii11 连通的版本,那么说明原图中 i,ji,j 在同一连通块内,可以二分做到 1log。总交互次数是 n+log2in+\sum \log_2 i,发现会被卡,我们不妨在二分的过程中求出把前 ii 个点连通的版本编号,这样可以去掉一开始的 nn 次询问,具体而言,如果存在 1j<i1\le j <i 使 i,ji,j 连通,那么可以直接调用版本 i1i-1 作为连通前 ii 个点的版本,否则 ii 不和前面任意一个点连通,在二分中的最后一次询问恰好使得前 ii 个点连通,直接调用这个版本即可。交互次数 log2i\sum \log_2 i

    #include <bits/stdc++.h>
    #define LL long long
    #define ull unsigned long long
    #define uint unsigned int
    using namespace std;
    
    int Connected(int a, int i, int j);
    void DescribeDesign(std::vector<std::pair<int, int>> result);
    const int N = 1e3 + 10;
    int idx[N];
    void ToyDesign(int n, int max_ops) {
    	idx[1] = 0; vector<pair<int, int> > edge;
    	for (int i = 2; i <= n; i ++) {
    		int l = 1, r = i - 1, res = 0;
    		while (l <= r) {
    			int mid = (l + r) >> 1;
    			int t = Connected(idx[mid], 1, i); idx[i] = t;
    			if (t == idx[mid]) res = mid, r = mid - 1;
    			else l = mid + 1;
    		} 
    		if (res) edge.push_back({res, i}), idx[i] = idx[i - 1];
    	}
    	DescribeDesign(edge); return ;
    }
    
    • 1

    信息

    ID
    10181
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者