[CSP-S模拟测试]:x(数学+并查集)
题目背景
$\frac{1}{4}$遇到了一道水题,叒完全不会做,于是去请教小$D$。小$D$都没看就切掉了这题,嘲讽了$\frac{1}{4}$一番就离开了。于是,$\frac{1}{4}$只好来问你,这道题是这样的:
题目描述
给定一个长度为$n$的正整数序列$\{a_i\}$。
将$\{1,2,...,n\}$划分成两个非空集合$S$、$T$,使得$gcd(\prod_{i\in S}a_i,\prod_{i\in T}a_i)=1$。
求划分方案数,对$10^9+7$取模。
输入格式
从文件$x.in$中读入数据。
第一行,一个非负整数$t$,代表数据组数。
每组数据的第一行,一个正整数$n$。
第二行,$n$个正整数,代表$\{a_i\}$。
输出格式
输出到文件$x.out$中。
输出$t$行,每行一个非负整数,代表答案对$10^9+7$取模的结果。
样例
样例输入:
3
3
2 3 1
3
2 3 6
4
2 3 6 1
样例输出:
6
0
2
数据范围与提示
样例解释:
$\bullet$第$1$组数据,任意一种非空集合划分均满足。
$\bullet$第$2$组数据,任意一种非空集合划分均不满足。
$\bullet$第$3$组数据,$S=\{1,2,3\},T=\{4\},gcd(a_1\times a_2\times a_3,a_4)=1$,或者$S=\{4\},T=\{1,2,3\},gcd(a_4,a_1\times a_2\times a_3)=1$。
数据范围:
保证,$0\leqslant t\leqslant 5,1\leqslant n\leqslant 10^5,1\leqslant a_i\leqslant 10^6$。
题解
似乎有一个很显然的性质:$gcd\neq 1$的连边,连通块个数为$cnt$,那么答案为$2^{cnt}−2$。
然而我考场上却没有想出来,想了一晚上才想明白,但是好多人都觉得这很显然,智商还是硬伤哇……
其他的没啥说的了,并查集维护一下联通块数就好了。
时间复杂度:$\Theta(1000000\times k)$($k$为很小的常数)。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int n;
int a[100001],fa[100001];
int que[80000],lst[80000];
bool v[1000001],vis[1000001];
long long ans;
vector<int> prime[1000001];
void pre_work()
{
ans=0;
memset(lst,0,sizeof(lst));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)fa[i]=i;
}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void get_prime()
{
for(int i=2;i<=1000000;i++)
{
if(v[i])continue;que[++que[0]]=i;
for(int j=i;j<=1000000;j+=i)
{
v[j]=1;
prime[j].push_back(que[0]);
}
}
}
long long qpow(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
int main()
{
get_prime();
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
pre_work();
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=0;j<prime[a[i]].size();j++)
if(!lst[prime[a[i]][j]])lst[prime[a[i]][j]]=i;
else fa[find(i)]=find(lst[prime[a[i]][j]]);
for(int i=1;i<=n;i++)
if(!vis[find(i)])
{
vis[find(i)]=1;
ans++;
}
printf("%lld\n",(qpow(2,ans)-2+mod)%mod);
}
return 0;
}
rp++
[CSP-S模拟测试]:x(数学+并查集)的更多相关文章
- [CSP-S模拟测试]:影子(并查集+LCA)
题目描述 一个人有很多的影子,新的旧的,他们不断消失重来.学者的影子在他苍白色的精神图景里成为了$n$个黑色的点,他们伸长的触手交叉形成了一颗黑色的树.假使每个影子点拥有一个权值$d_i$,黑色的树边 ...
- 【NOIP模拟_54测试】【并查集】【二进制】【搜索】【区间序列类】
第一题 Mushroom的序列 大意: 给一个序列,求一段连续最长区间满足:最多改变一个数,使得区间是严格的上升子序列. 解: 直接扫描一遍,记一个最长上升子序列编号.然后从每一个编号为1 的点来判断 ...
- Codeforces 1131 F. Asya And Kittens-双向链表(模拟或者STL list)+并查集(或者STL list的splice()函数)-对不起,我太菜了。。。 (Codeforces Round #541 (Div. 2))
F. Asya And Kittens time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- CSP 201703-4 地铁修建【最小生成树+并查集】
问题描述 试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市 ...
- 蓝桥杯模拟赛 引爆炸弹-并查集+DFS
引爆炸弹 在一个 n×m的方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去. 现在为了引爆地图上的所有炸弹, ...
- 并查集(Java实现)
(最好在电脑下浏览本篇博客...手机上看代码不方便) 当时学的时候看的一本印度的数据结构书(好像是..有点忘了..反正跟同学们看的都不一样...)...里面把本文提到的所有情况都提到了,我这里只是重复 ...
- SP5150 JMFILTER - Junk-Mail Filte(并查集)
直秒并查集.这题的难点就在于怎么删点.如果要删的是叶节点,那还好,直接刨掉即可 如果是中间节点甚至是根节点,那就不好办了..... solution: 对于独立一个点,我可以用邻接表模拟,然后用并查集 ...
- 【11.1校内测试】【快速幂DP】【带权并查集】【模拟】
Solution $jzy$大佬用了给的原根的信息,加上矩阵快速幂150行QAQ 然而$yuli$大佬的做法不仅好懂,代码只有50行! 快速幂的思想,把m看成要组成的区间总长度,每次将两段组合得到新的 ...
- 【8.22校内测试】【数学】【并查集】【string】
今天的t2t3能打出来80分的暴力都好满足啊QwQ.(%%%$idy$ 今天的签到题,做的时候一眼就看出性质叻qwq.大于11的所有数分解合数都可以用4.6.9表示,乱搞搞就可以了. #include ...
随机推荐
- vue-安装及新建一个项目
1.首先我们需要安装node.js,下载地址是:https://nodejs.org/en/ 之后是node.js的正常安装步骤: 接着打开window+R输入cmd回车进入命令行模块 2.确认nod ...
- HTML--JS 多列求和
<html> <head> <title>多列求和</title> <script type="text/javascript" ...
- _exit和exit的区别
在linux的标准库函数中,有一套称作高级I/O的函数,我们熟知的printf .fopen .fread .fwrite都在此列,他们也被称作缓冲I/O.其特征是对应每一个打开的文件,都存在一个缓冲 ...
- Java IO(2)
关于流的概念 Java 由流来完成具体的IO操作,虽然面对的是不同的外设(网络.鼠标.键盘)IO流使用与全部的外设,在底层Java已经将具体与物理设备交互的细节都处理好了. 流的分类: 从功能上 输入 ...
- app本身性能测试简介
app 性能测试指标: 1.启动时间 2.内存占用量,内存警告次数 3.页面渲染时间,刷新帧率 4.网络请求时间.流量消耗 5.UI阻塞次数,不可操作时长,主线程阻塞超过400毫秒次数 6.耗电功率 ...
- 进程池和multiprocess.Pool模块
一.为什么要有进程池 首先,创建进程需要消耗时间,销毁进程也需要时间.其次,即使开启了成千上万的进程,操作系统也不能让它们同时执行,这样反而会影响程序的效率.因此我们不能无限制的根据任务开启或者结束进 ...
- [fw]linux 下如何查看和踢除正在登陆的其它用户
linux 下如何查看和踢除正在登陆的其它用户 Posted on 2011/09/01 如何在linux下查看当前登录的用户,并且踢掉你认为应该踢掉的用户?请使用who这个命令来查看当前正在登录 ...
- HDU 4012 Paint on a Wall(状压+bfs)
Paint on a Wall Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) ...
- CodeChef Gcd Queries
Gcd Queries Problem code: GCDQ Submit All Submissions All submissions for this problem are ava ...
- XC6SLX45T-2FGG484C 原厂订购 原装正品
作为一家科研公司,保证的原厂品质和正规采购渠道是科学严谨的研发工作中重要的一环,更是保证研发产品可靠.稳定的基础.而研发中所遇到的各种不可预测的情况更是每个工程师向技术的山峰攀登中时会遇到的各种难题. ...