problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集)

solution:显然本题并不是那么容易啊!考场上想了好久。。

其实转化为上面的题意就简单多了,对于每一个元素分解质因数,就是在筛质数的时候记下每一个合数的最小质因子low[x],然后每一次不停的除low[x]

得到一个合数x',然后继续除low[x']即可,然后我们统计出含有每一个质因子的数有哪些(用一个二维vector),然后具有同种质因子的数必须放在同一个集合里面,

也就是说他们可以合并在一起,考虑并查集处理,就把每一个质因子把对应的数全部合并在一起,然后最后统计剩下的没有交集的最终不能再合并的互异块的个数tot

考虑用tot分成两个不同的非空集合,显然是2 tot -2,快速幂处理即可。

复杂度O(n log n)

code:

# include <bits/stdc++.h>
# define int long long
# define pow Pow
using namespace std;
const int M=1e6+;
const int mo=1e9+;
bool prime[M];
int low[M],a[M],f[M],n;
vector<int>r[M];
inline int read()
{
int X=,w=; char c=;
while (!(c>=''&&c<='')) w|=c=='-',c=getchar();
while (c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
void getprime(int limit)
{
memset(low,,sizeof(low));
memset(prime,true,sizeof(prime));
for (int i=;i<=limit;i++) {
if (!prime[i]) continue;
for (int j=i+i;j<=limit;j+=i) {
if (low[j]==) low[j]=i;
prime[j]=false;
}
}
}
int father(int x)
{
if (f[x]==x) return x;
f[x]=father(f[x]);
return f[x];
}
int calc(int x,int y)
{
int fx=father(x),fy=father(y);
f[fx]=fy;
}
void solve(int id)
{
int num=a[id];
while (low[num]) {
r[low[num]].push_back(id);
int tmp=low[num];
while (num%tmp==) num/=tmp;
}
r[num].push_back(id);
}
int pow(int x,int n)
{
int ans=;
while (n) {
if (n&) ans=ans*x%mo;
x=x*x%mo;
n>>=;
}
return ans%mo;
}
signed main()
{
int T=read();
while (T--) {
n=read();
int MAX=;
for (int i=;i<=n;i++) {
a[i]=read(); f[i]=i;
MAX=max(MAX,a[i]);
}
getprime(MAX);
for (int i=;i<=M;i++) r[i].clear();
for (int i=;i<=n;i++) solve(i);
for (int i=;i<=M;i++) {
if (r[i].size()==) continue;
int k=r[i][];
for (int j=;j<r[i].size();j++) calc(k,r[i][j]);
}
int ret=;
for (int i=;i<=n;i++) if (f[i]==i) ret++;
printf("%lld\n",(pow(,ret)%mo-+mo)%mo);
}
return ;
}

sol:分成两组然后每一组的人都互相认识,显然想到对每一个联通块01染色分成不同的集合

对于每一个联通块统计出0的块的个数1的块的个数,显然0或者1的个数为n/2最好才会使 calc(i)+calc(n-i)最小

其中calc(x)=x(x-1)/2,

由于每一个块我们只能有1或者0,那么设f[i][j]表示前i个块,选择0或者1的块为j是否可能

转移的话就是

f[i][j]|=f[i-1][j-a[i].cnt0]|f[i-1][j-a[i].cnt1]

然后j从n/2向左枚举然后找到若f[n][j]合法

那么最小化 clac(j)+calc(n-j)即可

code:

# include <bits/stdc++.h>
# define int long long
using namespace std;
const int MAXN=;
int mp[MAXN][MAXN],n,m,col[MAXN];
bool f[MAXN][MAXN];
int cnt0,cnt1;
int o;
struct rec{ int cnt0,cnt1;}b[MAXN];
void dfs(int u,int fa,int c)
{
col[u]=c;
//printf("%d ; col=%d\n",u,col[u]);
if (c==) cnt0++; else cnt1++;
for (int v=;v<=n;v++) {
if (mp[u][v]==) continue;
if (col[v]!=-) {
if (col[v]!=c^) { puts("-1"); exit();}
else continue;
}
dfs(v,u,c^);
}
}
int calc(int x){ return x*(x-)/;}
signed main()
{
scanf("%lld%lld",&n,&m);
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
if (i==j) mp[i][j]=false;
else mp[i][j]=true;
while (m--) {
int u,v; scanf("%lld%lld",&u,&v);
mp[u][v]=mp[v][u]=false;
}
memset(col,-,sizeof(col));
for (int i=;i<=n;i++)
if (col[i]==-) {
cnt0=cnt1=;
dfs(i,-,);
b[++o].cnt1=cnt1;
b[++o].cnt0=cnt0;
}
//f[i][j]前i个集合,到达A中有j个是否成立
//f[i][j]|=f[i-1][j-b[i].cnt0]|f[i-1][j-b[i].cnt1]
memset(f,false,sizeof(f));
f[][b[].cnt1]=f[][b[].cnt0]=true;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
f[i][j]=f[i][j]|f[i-][j-b[i].cnt0]|f[i-][j-b[i].cnt1];
int Ans=n*n*;
for (int i=;i<=n;i++)
if (f[n][i]) Ans=min(Ans,calc(i)+calc(n-i));
cout<<Ans<<endl;
return ;
}

HGOI 20181103 题解的更多相关文章

  1. HGOI 20181028 题解

    HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...

  2. HGOI 20190310 题解

    /* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...

  3. HGOI 20190303 题解

    /* 记一串数字真难. 5435 今天比赛又是hjcAK的一天. 今天开题顺序是312,在搞T1之前搞了T3 昨天某谷月赛真是毒瘤. 但是讲评的同学不错,起码T4看懂了... 构造最优状态然后DP的思 ...

  4. HGOI 20180224 题解

    /* The Most Important Things: ljc chat with fyh on QQTa说期末考Ta数学74分感觉不好但是我觉得fyh是地表最强的鸭~~(of course en ...

  5. HGOI 20190218 题解

    /* 又是AK局... hjc又双叒叕AK了... Hmmm...我侥幸 */ Problem A card 给出无序序列a[]可以选择一个数插入到合适的位置作为一次操作,至少多少次操作后可以把序列变 ...

  6. HGOI 20190217 题解

    /* for me,开训第一天 /beacuse 文化课太差被抓去补文化课了... 看一眼题 : AK局? 但是,Wa on test #10 in problem C 290! (就差那么一咪咪) ...

  7. NOI.AC 20181103 题解

    CF 1037B  Reach Median 班上 n个同学(n 是奇数)排成一排站队,为了美观,需要大家高度的中位数是 x. 你可以让同学们在脚下垫木板或者稍微蹲一点来达成这个目标.对任意一位同学的 ...

  8. HGOI 20181101题解

    /* 又是爆0的一天(不知道今年高考难不难,反正今天(信息学)真的难!) */ solution:对于两个数相加,有一个显然的结论就是要么不进位(相对于位数大的),要么(进最多一位) 然后对于整个数组 ...

  9. HGOI 20191108 题解

    Problem A 新婚快乐 一条路,被$n$个红绿灯划分成$n+1$段,从前到后一次给出每一段的长度$l_i$,每走$1$的长度需要$1$分钟. 一开始所有红绿灯都是绿色的,$g$分钟后所有红绿灯变 ...

随机推荐

  1. EF Core中如何取消跟踪DbContext中所有被跟踪的实体

    首先定义一个DbContext的扩展类DbContextDetachAllExtension,其中包含一个DbContext的扩展方法DetachAll,用来取消跟踪DbContext中所有被跟踪的实 ...

  2. C3P0配置实战

    C3P0: 一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等. 默认情况下(即没有配置连接池的 ...

  3. go语言之行--结构体(struct)详解、链表

    一.struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程).struct的成员(也叫属性或字段)可以是任何类型,如普通类型.复合类型.函数.map.int ...

  4. MySql+Socket 完成数据库的增查Demo

    需求: 利用MySql数据库结合前端技术完成用户的注册(要求不使用Web服务技术),所以 Demo采用Socket技术实现Web通信. 第一部分:数据库创建 数据库采用mysql 5.7.18, 数据 ...

  5. 【干货】YUM安装PHP 7版本后,增加phalcon框架的报错解决

    目录 1.yum安装php 7.x版本,此处部署7.3版本 2.安装phalcon框架 2.1.PHP版本依赖关系 2.2.编译phalcon扩展模块 2.3.增加扩展文件 3.部署phalcon遇到 ...

  6. 计算机基础知识 一 Basic knowledge of computers One

    计算机硬件由CPU(Central Processing Unit).存储器.输入设备.输出设备组成. CPU通常由控制单元(控制器)和算数逻辑单元(运算器)组成. 运算器:负责进行算数运算和逻辑运算 ...

  7. Linux下安装maven(mvn命令)

    Maven(mvn)是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具(百度百科) 简单理解为一个打包 ...

  8. 用信鸽来讲解HTTPS的知识

    加密是一个很难理解的东西,这里头满是数学证明.不过,除非你是在开发一个加密系统,否则无需了解那些高阶的复杂知识. 如果你看这篇文章是为了创造下一个 HTTPS 协议,很抱歉,请出门左走,鸽子是远远不够 ...

  9. 12.18daily_scrum

    本软件中的最后一个界面——“关于”界面的设计已经开始进行,数据传输的内容也差不多进行过半,最主要的任务依旧在测试过程中,我们组接下来还是要大力加强测试的强度和数量,注意边际数据和错误数据的测试处理: ...

  10. 【Alpha阶段】M1事后报告

    时间:2015-11-13 23:30 地点:七公寓一楼会议室 参与人员:窝窝头全体成员(王若愚因事请假) 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述 ...