洛谷 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}$ 题解:线性齐次递推,先见洛谷题解, ...
随机推荐
- NX屏蔽窗口的按钮
有时候在激活一个命令按钮的时候,需要同时禁止掉另外一个或多个命令按钮 ''' <summary> ''' 取按钮是否敏感 ''' </summary> ''' <para ...
- (课内)信安数基RSA-level1&&2
注:(不求甚解的)攻击原理 以及(浅层的)算法解释已在图片中给出:文字部分主要讲一些python语法的东西. 代码需要库 gmpy2和libnum:加密算法还需要Crypto.Util.number ...
- Vue3学习(八)之 Vue CLI多环境配置
一.前言 这里相对于之前就没那么麻烦了,通俗点说就是使用配置文件来管理多环境,实现环境的切换. 二.实现切换 1.增加开发和生产配置文件 在web的根目录下,创建开发环境切换配置文件.env.dev, ...
- 【Java虚拟机10】ClassLoader.getSystemClassLoader()流程简析
前言 学习类加载必然离开不了sun.misc.Launcher这个类和Class.forName()这个方法. 分析ClassLoader.getSystemClassLoader()这个流程可以明白 ...
- Java序列元素替换
1.数组 直接赋值. 2.String (1) String是不可变的,只能将新的字符串重新赋给String变量.可使用substring进行拼接: String s="hello" ...
- ScatterLayout:分散布局在py中的引用
""" ScatterLayout:分散布局 """ from kivy.app import App from kivy.uix.scat ...
- java中this关键字总结
1.this是一个引用,也是一个变量,存储在JVM堆内存的Java对象内部. 2.this变量中保存的内存地址指向自身. 3.this可以在实例方法中使用,this指向当前正在执行这个动作的对象(th ...
- [no code][scrum meeting] Alpha 5
项目 内容 会议时间 2020-04-10 会议主题 后端技术讨论 会议时长 30min 参会人员 全体成员 $( "#cnblogs_post_body" ).catalog() ...
- Noip模拟34 2021.8.9
T1 Merchant 一眼二分,然后想了想维护凸包,好像并没有什么关系, 然后又想了想维护一个栈,发现跳指针细节过多不想打 最后直接打了二分,大点跑的飞快,感觉比较稳,出来$78$分 是没用神奇的$ ...
- 零基础入门Linux有什么好的学习方法吗?(超详细)
本节旨在介绍对于初学者如何学习 Linux 的建议,在这里不具体分析Linux的学习节点只分析对于零基础的伙伴的学习方法.那么如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Li ...