题解 洛谷P7384【「EZEC-6」】
概述
题号 | 难度 | \(AC\)时间及记录 |
---|---|---|
\(\texttt{P7384}\) | \(\texttt{洛谷难度:暂无评定}\) | \(\texttt{On 2021/02/21}\) |
解析
这道题我们考虑并查集暴力。
不难证明,众所周知,每两个数,他们在二进制下,
如果某一位同是\(1\),那么他们应该归为一组,
这样代价最小。
因此,学过状态压缩\(DP\)的同学应该已经知道怎么做了。
如果某个数是\(0\),记得特判。
某一位没用过特殊处理,
即可\(AC\)。
时间复杂度\(\mathcal{O(nlogn)}\)
代码
/*
Author:Xsmyy
Problem:P7384
Date:2021/02/21
*/
#include<bits/stdc++.h>
#define BetterIO ios::sync_with_stdio(false)
using namespace std;
int N;
int Fa[101];
bool Used[101];
int A[101][101];
#define getchar()(X==Y&&(Y=(X=sRead)+fread(sRead,1,1<<21,stdin),X==Y)?EOF:*X++)
char sRead[1<<21],*X=sRead,*Y=sRead;
inline long long Read()
{
register long long Return,Flag;
Return=Flag=0;
register char C;
C=getchar();
for(;!isdigit(C);C=getchar())
{
Flag^=!(C^45);
}
for(;isdigit(C);C=getchar())
{
Return=(Return<<1ll)+(Return<<3ll)+(C^'0');
}
if(Flag)
{
Return=-Return;
}
return Return;
}
inline int Find(int X)
{
return X==Fa[X]?X:Fa[X]=Find(Fa[X]);
}
inline void Merge(int X,int Y)
{
Fa[Find(X)]=Find(Y);
}
int main(void)
{
BetterIO;
register int i,j;
N=Read();
for(i=0;i<=64;i++)
{
Fa[i]=i;
}
register int Ans;
Ans=0;
for(i=1;i<=N;i++)
{
register long long X;
X=Read();
if(!X)
{
Ans++;
continue;
}
register int One;
One=-1;
register long long i;
for(i=0;(1ll<<i)<=X;i++)
{
if((1ll<<i)&X)
{
if(One!=-1)
{
A[i][One]=true;
}
else
{
One=i;
}
Used[i]=true;
}
}
}
for(i=0;i<=64;i++)
{
for(j=0;j<=64;j++)
{
if(A[i][j])
{
Merge(i,j);
}
}
}
for(i=0;i<=64;i++)
{
if(Fa[i]==i&&Used[i])
{
Ans++;
}
}
cout<<Ans<<endl;
return 0;
}
转载请注明出处:http://www.yaohuano3.com/article/20230526/700970.html