• P5937 [CEOI1999]Parity Game


     (奇偶性真是太能整活了)

    找到第一句假话,显然在此之前需要找到一种方式存储先前给定的所有关系.

    为什么会想到"关系"呢?观察每一行给出的三元有序组,前两者是两个数值,最后一者表示某种状态,即奇偶性.应该可以联想到,两个数值表达的对象具有着此状态所表示的关系.

    也就是说,给定的数据是(对象A,对象B,A和B的关系),不要解读成了(数值,数值,一个未定的奇数/偶数),或者(对象,对象,一个未定的奇数/偶数),两个对象的某个共同数值有其他的处理方法(见借教室),而两个对象的关系使用并查集处理.在本题中,一个区间内所有1的数量即该区间所有数的和,表示区间数值的和使用前缀和数组:

      如果区间[a,b]中有偶数个1,那么(前缀和数组)s[b]-s[a-1]为偶数,即s[b]与s[a-1]奇偶性相同.

      如果区间[a,b]中有奇数个1,那么(前缀和数组)s[b]-s[a-1]为奇数,即s[b]与s[a-1]奇偶性不同.


    接下来的事情就是用拓展域并查集处理了(也有人把这个叫种类并查集).观察数据范围,会想到离散化的.

    实际上并不需要创建这个前缀和数组.因为并不需要对其进行任何操作,也没有可用的数据.注意区间[a,b]对应的对象是s[a-1]和s[b].

    #include <algorithm>
    #include <cstdio>
    #include <string>
    #include <iostream>
    #include <queue>
    using namespace std;
    
    struct S{
        int l, r, v;
    };
    deque<S> q;
    int n, m, ind, ans, fa[10010], dis[10010];
    
    void discrete() {
        sort(dis + 1, dis + 1 + ind);
        ind = unique(dis + 1, dis + 1 + ind) - dis - 1;
    }
    int query(int x) { return lower_bound(dis + 1, dis + 1 + ind, x) - dis; }
    int get(int x){if(fa[x] == x) return x; return fa[x] = get(fa[x]);}
    void merge(int x, int y) {fa[get(y)] = fa[get(x)];}
    
    int main(){
        cin >> n >> m;
        ans = m;
        for(int i = 1; i <= m; i++) {
            int a, b;
            string c;
            cin >> a >> b >> c;
            a--;
            q.push_back({a, b, c == "even" ? 1 : -1});
            dis[++ind] = a, dis[++ind] = b;
        }
        discrete();
        for(int i = 1; i <= ind * 2; i++) fa[i] = i;
    
        while(!q.empty()){
            S cur = q.front();
            q.pop_front();
            int x = query(cur.l), y = query(cur.r), z = cur.v;
    
            if(z == -1){    // odd, diff
                if(get(x) == get(y)){ans = m - q.size() - 1; break;}
                merge(y, x + ind), merge(x , y + ind);
            }else{          // even, same
                if(get(x) == get(y + ind)){ans = m - q.size() - 1; break;}
                merge(x, y), merge(x + ind, y + ind);
            }
        }
    
        cout << ans << endl;
    
        return 0;
    }
    P5937

    玩奇偶性的还有这题.可以看出来奇偶性可以往前缀和上面想想.

  • 相关阅读:
    'IDataObject': ambiguous symbol的解决方法
    捕获windows系统的sleep或hibernate状态
    CallingConvention理解
    Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))
    .Net Managed C++如何获取当前线程id和当前进程id
    div垂直居中于div中
    父级是relative,子级为absolute的情况下,子级宽度自适应
    background-img高度固定,图片自适应
    如何让两个input紧挨着.
    C# 调用百度短链接api
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14409657.html
Copyright © 2020-2023  润新知