zoukankan      html  css  js  c++  java
  • [cf] Invoking the Magic

    题意后面在来补充

    离散化+并查集

    虽然我现在还是没太明白为什么用并查集,我觉得就是当find(a) == find(b)的时候就相当于是有个环了,就可以清空了。

    对于离散化我现在还有点不清楚,上次看了y总的板子也没有深入理解先在复习下离散化的知识

    离散化

    步骤

    1. 排序
    2. 去重
    3. 二分索引
    vector<int> alls; // 存储所有待离散化的值
    sort(alls.begin(), alls.end()); // 将所有值排序
    alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素
    
    // 二分求出x对应的离散化的值
    int find(int x) // 找到第一个大于等于x的位置
    {
        int l = 0, r = alls.size() - 1;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (alls[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return r + 1; // 映射到1, 2, ...n
    }
    
    

    写了很久,还是没过,有点难受,不知道是哪里错了,但是思路是这个思路等以后再看,重新写一遍把,代码先放在这里

    #include <bits/stdc++.h>
    using namespace std;
    ///Invoking the Magic
    
    const int N = 1e5 +10;
    int a[N];///原数组
    int b[N];///原数组
    
    
    int d[N];///并查集
    int cnt[N];
    vector<int> v;
    
    
    void file()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:/workProgram/test.txt","r",stdin);
        //freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
    #endif
    }
    
    
    int Find(int x)
    {
        int l = 0, r = v.size() - 1;
        while( l < r ){
            int mid = (l + r ) >> 1;
            if( v[mid] >= x ) r = mid;
            else l = mid + 1;
        }
        return r;
    }
    
    int Search(int x)
    {
        if(d[x] != x) d[x] = Search(d[x]);
        return d[x];
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        file();
        int n ;
        cin >> n;
        while(n--){
            int m;
            cin >> m;
            ///离散化
            for(int i = 0; i < m ; i++){
                cin >> a[i] >> b[i];
                v.push_back(a[i]);
                v.push_back(b[i]);
            }
    
            sort(v.begin(),v.end());
            v.erase( unique(v.begin(),v.end()) , v.end());
    //        cout << v.size();
    //        for(int i = 0 ; i < v.size() ; i++){
    //            cout << v[i] << endl;
    //        }
            for(int i = 0 ;i < m ; i++){
                d[i] = i;
                cnt[i] = 1;
            }
    
            ///并查集
            for(int i = 0 ; i < m; i++){
                a[i] = Find(a[i]);
                b[i] = Find(b[i]);
                //cout << a[i] << " " << b[i] << endl;
            }
    
            int ans = 0;
            for(int i = 0; i < m ;i++){
                int fa = Search(a[i]);
                int fb = Search(b[i]);
    
                if(fa != fb){
                    d[fa] = fb;
                    cnt[fb] += cnt[fa];
                    ans = max( ans,cnt[fb] );
                }
            }
    
            cout << ans << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    Java集合框架:Collections工具类
    百度编辑器多图上传返回图片绝对路径问题
    iOS开发中“此证书的签发者无效”的解决方式
    codeblocks如何watch指针
    codeblocks如何watch数组
    printf不支持%lf
    doxygen可以生成C/C++代码的文档(根据注释)
    codeblocks中右键源文件没有Rename选项?
    codeblocks中给GCC编译器加参数
    codeblocks设置当前行高亮
  • 原文地址:https://www.cnblogs.com/hoppz/p/14022541.html
Copyright © 2011-2022 走看看