首页 > 其他分享 >[CEOI1999] Parity Game(并查集)

[CEOI1999] Parity Game(并查集)

时间:2024-09-29 13:13:31浏览次数:8  
标签:Parity typedef int 查集 begin long Game vx inline

方法1:带权路径维护
本题核心:[a,b]之间有奇数个1转换为s[a-1]^s[b] = 1,从而转向并查集

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
vector<int> vx;
inline void divide() {sort(vx.begin(),vx.end());vx.erase(unique(vx.begin(),vx.end()),vx.end());}
inline int mp(int x) {return upper_bound(vx.begin(),vx.end(),x)-vx.begin();}
inline int log_2(int x) {return 31-__builtin_clz(x);}
inline int popcount(int x) {return __builtin_popcount(x);}
inline int lowbit(int x) {return x&-x;}
const int N = 5010;
//d[i]表示i到根节点的异或值是1还是0
int f[N<<1],d[N<<1],sz[N<<1];
int find(int u)
{
    if(f[u] == u) return u;
    int t = find(f[u]);
    d[u] ^= d[f[u]];
    return f[u] = t;
}
void merge(int u,int v,int st)
{
    int f1 = find(u), f2 = find(v);
    //要求d[u]^d[f1]^d[v] = st,反推d[f1]
    f[f1] = f2, d[f1]^=(d[u]^d[v]^st);
}
void solve()
{
    int n;
    cin>>n;
    int m;
    cin>>m;
    for(int i=1;i<=m*2;++i) f[i] = i;
    vector<array<int,3>> a(m);
    for(int i=0;i<m;++i)
    {
        string op;
        cin>>a[i][0]>>a[i][1]>>op;
        //[a,b]中有奇数个1即s[a-1]和s[b]的奇偶性不同
        vx.push_back(a[i][0]-1);
        vx.push_back(a[i][1]);
        if(op == "even") a[i][2] = 0;
        else a[i][2] = 1;
    }
    //注意离散化需要erase掉重复的内容
    divide();
    for(int i=0;i<m;++i)
    { 
        int u = mp(a[i][0]-1), v = mp(a[i][1]), st = a[i][2];
        //cout<<u<<' '<<v<<' '<<st<<'\n';
        if(find(u) == find(v))
        {
            if(d[u]^d[v] != st) 
            {
                cout<<i<<'\n';return ;
            }
        }
        else
        {
            merge(u,v,st);
        }
    }
    cout<<m<<'\n';
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T = 1;
	//cin>>T;
	while(T--)
	{
		solve();
	}
}

方法2扩展域

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
vector<int> vx;
inline void divide() {sort(vx.begin(),vx.end());vx.erase(unique(vx.begin(),vx.end()),vx.end());}
inline int mp(int x) {return upper_bound(vx.begin(),vx.end(),x)-vx.begin();}
inline int log_2(int x) {return 31-__builtin_clz(x);}
inline int popcount(int x) {return __builtin_popcount(x);}
inline int lowbit(int x) {return x&-x;}
const int N = 5010;
//d[i]表示i到根节点的异或值是1还是0
int f[N<<2];
int find(int u)
{
    if(f[u] == u) return u;
    return f[u] = find(f[u]);
}
void merge(int u,int v)
{
    int f1 = find(u), f2 = find(v);
    f[f1] = f2;
}
void solve()
{
    int n;
    cin>>n;
    int m;
    cin>>m;
    //拆点
    for(int i=1;i<=m*4;++i) f[i] = i;
    vector<array<int,3>> a(m);
    for(int i=0;i<m;++i)
    {
        string op;
        cin>>a[i][0]>>a[i][1]>>op;
        //[a,b]中有奇数个1即s[a-1]和s[b]的奇偶性不同
        vx.push_back(a[i][0]-1);
        vx.push_back(a[i][1]);
        if(op == "even") a[i][2] = 0;
        else a[i][2] = 1;
    }
    //注意离散化需要erase掉重复的内容
    divide();
    //用i*2表示i的偶数点,用i*2-1表示i的奇数点,表示sum[i]是奇数或者偶数
    for(int i=0;i<m;++i)
    { 
        int u = mp(a[i][0]-1), v = mp(a[i][1]), st = a[i][2];
        int ue = u*2, uo = u*2-1, ve = v*2, vo = v*2-1;
        //若st == 1则uo应该和ve合并,ue和vo合并
        if(st)
        {
            if(find(uo) == find(vo)||find(ue) == find(ve))
            {
                cout<<i<<'\n';return ;
            }
            merge(uo,ve);merge(ue,vo);
        }
        else
        {
            if(find(ue) == find(vo)||find(uo) == find(ve))
            {
                cout<<i<<'\n';return ;
            }
            merge(uo,vo);merge(ue,ve);
        }
    }
    cout<<m<<'\n';
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T = 1;
	//cin>>T;
	while(T--)
	{
		solve();
	}
}

标签:Parity,typedef,int,查集,begin,long,Game,vx,inline
From: https://www.cnblogs.com/ruoye123456/p/18439505

相关文章

  • [NOI2002] 银河英雄传说(带权并查集)
    带权并查集稍微注意下细节、#include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefunsignedintuint;typedefvector<string>VS;typedefve......
  • Supermarket(并查集)
    考虑利润从高到底排序,优先把利润最高的填到最接近过期的空余位置贪心证明:如果当前a[i]被填入而填入了比最靠近过期前面的位置显然不会更优,如果没有被填入而放了另一组方案利润更大,则把属于a[i]的位置换成a[i]一定更优,两者矛盾#include<bits/stdc++.h>usingnamespacestd;#def......
  • P1955 [NOI2015] 程序自动分析(并查集)
    相等放并查集里,不等直接判断#include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefunsignedintuint;typedefvector<string>VS;typedefv......
  • 数据结构:速通并查集
    并查集用来干什么:处理不相交的集合的合并以及查询相交集合的个数等情况例题(自行搜索):36024年第一批笔试算法题传染病防控 并查集具有三个操作initfindunioninit初始化集合,将当前所有节点的父节点设置为自己intfa[]=newint[10000];intsize[]=newint[10000];//这里是......
  • 梦幻西游端游多开搬砖攻略,GameViewer远程助力高效查看操控搬砖进度
    想要电脑装进手机,手机实现多开梦幻西游搬砖,不占内存、不发烫就选网易GameViewer远程。作为梦幻西游的老玩家,拥有多个账号,都想要搬砖,这款软件就能让你的手机或是平板免费远控电脑,多开玩梦幻西游端游,而且不占内存,不发烫,高效查看操控搬砖进度。使用网易GameViewer远程进行梦......
  • 手机如何五开玩梦幻西游端游?用GameViewer远程手机免费畅玩梦幻西游
    用手机就能免费玩梦幻西游端游,还可以随时查看挂机进度!想要实现这一点,就用网易GameViewer远程,而且不光手机可以玩梦幻西游端游,平板也能免费玩,并为你实现五开玩梦幻西游端游。那么,通过GameViewer远程你都能体验到什么呢?你能体验到4K蓝光144帧的高画质和百分百还原梦幻......
  • GAMES101(作业7)
     作业七题目:实现pathTracing,仅修改castRay(constRayray,intdepth)函数,在其中实现PathTracing算法代码框架://OBJ-loader模型加载库 global:全局变量/函数 vector:Vector3f,Vector2f类floatnorm(){returnstd::sqrt(x*x+y*y+z*z);}/*向量长度......
  • Codeforces Round 959 (Div. 1 + Div. 2) C. Hungry Games题解
    CodeforcesRound959(Div.1+Div.2)C.HungryGames题解题目链接大致题意:给定一个长度为n的数组,并且给出一对l,r表示一个区间,如果∑i......
  • 如何使用 pygame.image.load() 加载图像?
    我只是想知道语法。如何使用pygame.image.load()加载图像?举个例子,我想加载一个名为cat.png的图像-并输入这个pygame.image.load('cat.png')那么,图像cat.png应该保存在哪里?当然可以,让我们来分解一下如何使用Pygame加载图像。1.导入和初始化首先,你......
  • 【888题竞赛篇】第十二题,2024ICPC网络赛第二场-游戏(Game)
    这里写自定义目录标题更多精彩内容256题算法特训课,帮你斩获大厂60W年薪offer原题2024ICPC网络赛第二场真题-游戏B站动画详解问题分析思路分析核心思路递归关系边界条件优化思路:辗转相减与辗转相除最终递归关系算法实现代码详解标准代码程序C++代码Java代码Python代码J......