洛谷 P7451 - [THUSCH2017] 杜老师(线性基+根分+结论题)
看到乘积为平方数我们可以很自然地想到这道题,具体来说,我们对 \(1\sim 10^7\) 中所有质因子标号 \(1,2,\cdots,\pi(10^7)\),对于 \(x\in[l,r]\) 中的数我们采用试除法对 \(x\) 分解质因数并求出每个质因子次数的奇偶性。我们建一个每个元素都是 \(0/1\) 的向量 \(b\),对于质因子 \(p_i\),如果 \(p_i\) 在 \(x\) 的质因数分解式中次数为奇数,那么 \(b\) 的第 \(i\) 位为 \(1\),否则 \(b\) 的第 \(i\) 位为 \(1\),那么一个集合 \(S\) 中所有数的乘积为完全平方数当且仅当 \(S\) 中所有数表示的向量在 \(\bmod 2\) 意义下的和为零向量。这显然可以通过线性基维护,01 向量的异或运算可用 bitset 优化。记线性基大小为 \(x\),那么答案为 \(2^{r-l+1-x}\)。复杂度 \(\dfrac{n\pi^2(n)}{\omega}\approx 10^{18}\),无法通过。
考虑优化,注意到对于所有 \(>\sqrt{10^7}\) 的因子,它在所有数中至多出现一次。我们考虑只对 \(1\sim\sqrt{10^7}\) 中的质数编号——这样的质数的个数大约在 \(450\) 左右。记 \(mxp_i\) 为 \(i\) 最大的质因子。我们对每个 \(>\sqrt{n}\) 的质因子 \(p\) 额外建一个 bitset 维护最大质因子为 \(p\) 的数的质因子情况,当我们插入某个数 \(x\) 的时候,若 \(mxp_x>\sqrt{10^7}\),我们就检验 \(mxp_x\) 对应的 bitset 是否为空,如果是那就令该 bitset 为 \(x\) 表示的向量,否则就用 \(x\) 表示的向量异或上 \(mxp_x\) 对应的 bitset 再插入线性基,不难发现该操作与线性基实际上是等价的,只不过将线性基的规模由 \(\pi(10^7)\approx 10^6\) 缩小到了 \(\pi(\sqrt{10^7})\approx 450\)。不过复杂度还是高达 \(\dfrac{n\pi^2(\sqrt{n})}{\omega}\approx 10^{10}\),还是无法通过。
下一步就非常考验观察能力了,注意到当区间长度大于某个临界值的时候,线性基是非常容易塞满的,在这种情况下所有在 \([l,r]\) 中出现过的质因子都会被加入线性基中,因此我们只需统计 \([l,r]\) 中有多少个质因子即可,具体来说枚举所有 \([1,r]\) 的质因子 \(p\) 并检验是否有 \(\lfloor\dfrac{l-1}{p}\rfloor\ne\lfloor\dfrac{r}{p}\rfloor\),累加入答案即可,复杂度 \(\pi(10^7)\)。那么这个临界值是多少呢?打个表发现临界值大约在 \(2\sqrt{n}\) 左右,因此可以像根号分治一样对区间长度 \(<2\sqrt{n}\) 的询问跑线性基,对区间长度 \(\ge 2\sqrt{n}\) 的询问枚举质因子,这样复杂度就降到了 \(6000\times\dfrac{450^2}{64}+6\times 10^6\approx10^7\),即可通过此题。
总之这道题就是线性基+根号分治+猜结论的 nb tea %%%
const int MAXN=1e7;
const int MAXB=446;
const int MOD=998244353;
int pw2[MAXN+5],lim=3162;bitset<MAXN+5> vis;
int mxp[MAXN+5],pr[MAXN/10+5],prcnt=0,id[MAXN+5];
bitset<MAXB+5> hi[MAXN/10+5];bool used[MAXN/10+5];
int need[MAXN/10+5],need_n=0;
bitset<MAXB+5> b[MAXB+5];
void sieve(int n){
for(int i=2;i<=n;i++){
if(!vis[i]){pr[++prcnt]=i;mxp[i]=i;id[i]=prcnt;}
for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;mxp[pr[j]*i]=max(mxp[i],pr[j]);
if(i%pr[j]==0) break;
}
}
}
int cnt=0;
void ins(bitset<MAXB+5> x){
for(int i=MAXB;i;i--) if(x[i]){
if(!b[i].any()){b[i]=x;return;}
else x^=b[i];
} cnt++;
}
void add(int x){
int mx=mxp[x];if(mx>=lim) x/=mx;
bitset<MAXB+5> bt;
while(x!=1){
int v=mxp[x],par=0;
while(x%v==0) x/=v,par^=1;
bt[id[v]]=par;
}
if(mx>=lim){
if(used[id[mx]]) bt^=hi[id[mx]];
else{
used[id[mx]]=1;hi[id[mx]]=bt;
need[++need_n]=id[mx];
return;
}
} ins(bt);
}
void solve(){//remember to clear it at last
int l,r;scanf("%d%d",&l,&r);
if(r-l+1<=7000){
for(int i=l;i<=r;i++) add(i);printf("%d\n",pw2[cnt]);
for(int i=1;i<=need_n;i++) used[need[i]]=0,hi[need[i]].reset(),need[i]=0;
need_n=0;for(int i=1;i<=MAXB;i++) b[i].reset();cnt=0;
} else {
int tot=r-l+1;
for(int i=1;i<=prcnt;i++){
if(pr[i]>r) break;
if((l-1)/pr[i]!=r/pr[i]) --tot;
} printf("%d\n",pw2[tot]);
}
}
int main(){
pw2[0]=1;for(int i=1;i<=MAXN;i++) pw2[i]=2*pw2[i-1]%MOD;
sieve(MAXN);int qu;scanf("%d",&qu);while(qu--) solve();
return 0;
}
洛谷 P7451 - [THUSCH2017] 杜老师(线性基+根分+结论题)的更多相关文章
- 洛谷CF895C Square Subsets(线性基)
洛谷传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 题意: 给你n个数,每个数<=70,问有多少个集合,满足集合中所有数相乘是个完全平方数(空集除外) 题解: 完全看不出这玩意儿和线性基有什 ...
- 题解——洛谷P3812【模板】线性基
学了下线性基 使用好像并不复杂 打了板子 但是要注意位运算优先级 #include <cstdio> #include <algorithm> #include <cst ...
- 洛谷P3292 [SCOI2016] 幸运数字 [线性基,倍增]
题目传送门 幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的 ...
- 洛谷P3812 【模板】线性基 [线性基]
题目传送门 线性基 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: 仅一行 ...
- 洛谷P3812 【模板】线性基
题目背景 这是一道模板题. 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: ...
- 洛谷P3857 [TJOI2008]彩灯(线性基)
传送门 线性基裸题 直接把所有的状态都带进去建一个线性基 然后答案就是$2^{cnt}$($cnt$代表线性基里数的个数) //minamoto #include<cstdio> #inc ...
- 洛谷P4570 [BJWC2011]元素(线性基)
传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 考虑贪心 将所有的矿石按价值从大到小排序 如果一块矿石不会和之前的编号异或为0就加入 这个只要判一下它能不能加进线性基里就可以了 据说这个贪心的证明 ...
- 洛谷P3292 [SCOI2016]幸运数字 线性基+倍增
P3292 [SCOI2016]幸运数字 传送门 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在 ...
- [洛谷P4723]【模板】线性递推
题目大意:求一个满足$k$阶齐次线性递推数列$a_i$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n-i}$ 题解:线性齐次递推,先见洛谷题解, ...
随机推荐
- C# 如何使用代码添加控件及控件事件
1.首先简单设计一下界面: 添加了Click事件 <Window x:Class="WpfApp.MainWindow" xmlns="http://schemas ...
- 按照工业标准1英寸=25.4mm,而在电子元件成像领域Sensor尺寸1英寸=16mm。
按照工业标准1英寸=25.4mm,而在电子元件成像领域Sensor尺寸1英寸=16mm. 我们平常所说的CCD/CMOS的尺寸,实际上是指Sensor对角线的长度,这一点跟我们平常所说的屏幕尺寸是一样 ...
- linux中的分号 && ||
几个符号的用法 ; 顺序地独立执行各条命令, 彼此之间不关心是否失败, 所有命令都会执行. && 顺序执行各条命令, 只有当前一个执行成功时候, 才执行后面的. & 放在启动参 ...
- PicGo插件
前言:主要介绍PicGo插件,这里的图床上传软件是PicGo-Core,使用命令行操作 PicGo_Path:自己的PicGo安装路径,如果通过Typora一般安装位置位于 C:\Users\自己的主 ...
- JavaScript复习 1
概括及使用方法: JavaScript编写规范 一般放在<head>-</head>中间 逐行被执行,越短越好 大小写敏感 语句是基本单位 通常以分号表示语句结束 多行语句可以 ...
- Linux系统编程之进程概念
注:本文部分图片来源于网络,如有侵权,请告知删除 1. 什么是进程? 在了解进程概念之前,我们需要先知道程序的概念. 程序,是指编译好的二进制文件,这些文件在磁盘上,并不占用系统资源. 进程,指的是一 ...
- Java 代码执行流程
Java 代码执行流程 类加载过程 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 类加载时机:代码使用到这个类时 验证阶段 &qu ...
- Oracle 表空间和权限
表空间 表空间是数据库的逻辑划分,一个表空间只能属于一个数据库.所有的数据库对象都存放在指定的表空间中.但主要存放的是表,所以称作表空间. Oracle中很多优化都是基于表空间的设计理念而实现的,一个 ...
- C# for Beginner Part 21 to 30
Part 21 Inheritance in c# Why Inheritance Pillars(支架) of Object Oriented Programming 1,Inheritance(继 ...
- 我個人喜歡的一些Ubuntu的相關配置
1.vim vim安裝: sudo apt-get install vim-gtk vim美化:刚安装的VIM,可能界面并不是十分友好,我们可以更改vim的配置文件,按照我们的需求去修改它.在命令行下 ...