题面传送门

看到乘积为平方数我们可以很自然地想到这道题,具体来说,我们对 \(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] 杜老师(线性基+根分+结论题)的更多相关文章

  1. 洛谷CF895C Square Subsets(线性基)

    洛谷传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 题意: 给你n个数,每个数<=70,问有多少个集合,满足集合中所有数相乘是个完全平方数(空集除外) 题解: 完全看不出这玩意儿和线性基有什 ...

  2. 题解——洛谷P3812【模板】线性基

    学了下线性基 使用好像并不复杂 打了板子 但是要注意位运算优先级 #include <cstdio> #include <algorithm> #include <cst ...

  3. 洛谷P3292 [SCOI2016] 幸运数字 [线性基,倍增]

    题目传送门 幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的 ...

  4. 洛谷P3812 【模板】线性基 [线性基]

    题目传送门 线性基 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: 仅一行 ...

  5. 洛谷P3812 【模板】线性基

    题目背景 这是一道模板题. 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: ...

  6. 洛谷P3857 [TJOI2008]彩灯(线性基)

    传送门 线性基裸题 直接把所有的状态都带进去建一个线性基 然后答案就是$2^{cnt}$($cnt$代表线性基里数的个数) //minamoto #include<cstdio> #inc ...

  7. 洛谷P4570 [BJWC2011]元素(线性基)

    传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 考虑贪心 将所有的矿石按价值从大到小排序 如果一块矿石不会和之前的编号异或为0就加入 这个只要判一下它能不能加进线性基里就可以了 据说这个贪心的证明 ...

  8. 洛谷P3292 [SCOI2016]幸运数字 线性基+倍增

    P3292 [SCOI2016]幸运数字 传送门 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在 ...

  9. [洛谷P4723]【模板】线性递推

    题目大意:求一个满足$k$阶齐次线性递推数列$a_i$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n-i}$ 题解:线性齐次递推,先见洛谷题解, ...

随机推荐

  1. 从零到熟悉,带你掌握Python len() 函数的使用

    摘要:本文为你带来如何找到长度内置数据类型的使用len() 使用len()与第三方数据类型 提供用于支持len()与用户定义的类. 本文分享自华为云社区<在 Python 中使用 len() 函 ...

  2. vue3双向数据绑定原理_demo

    <!DOCTYPE html> <head> <meta charset="UTF-8" /> <meta name="view ...

  3. [no_code][Alpha]测试报告

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 2020春季计算机学院软件工程(罗杰 任健) 作业要求 测试报告 我们在这个课程的目标是 设计出一个OCR表单处理软件 这个作业在哪个具体方面 ...

  4. 使用jave2实现将wav格式的音频转换成mp3格式

    最近需要用到语音合成功能,网上查阅了一番,发现可以使用腾讯云的语音合成API来完成这个功能,但是腾讯云的api返回的是wav格式的音频文件,这个格式的文件有些不通用,因此需要转换成mp3格式的文件. ...

  5. luogu P4243 [JSOI2009]等差数列 题解

    前言: 这题真ex... 强烈谴责在题解里面放毒瘤题链接的屑出题人! 吐 ️ 解析: 这题分成两步走. 首先,既然题目中的修改操作是区间加等差数列,那么就容易想到在差分数组上进行操作. 然后就是相当恶 ...

  6. 2021.7.28考试总结[NOIP模拟26]

    罕见的又改完了. T1 神炎皇 吸取昨天三个出规律的教训,开场打完T2 20pts直接大力打表1h. 但怎么说呢,我不懂欧拉函数.(其实exgcd都忘了 于是只看出最大平方因子,不得不线性筛,爆拿60 ...

  7. MIPI归纳---为什么阻抗为100欧姆

    根据LVDS(Low Voltage Differential Signaling)电平定义的. LVDS差分信号PN两线最大幅度是350mV,内部一个恒流源电流是3.5mA.于是终端匹配电阻是100 ...

  8. 六步教你如何用PADS进行PCB设计?

    在使用PADS进行PCB设计的过程中,需要对印制板的设计流程以及相关的注意事项进行重点关注,这样才能更好的为工作组中的设计人员提供系统的设计规范,同时也方便设计人员之间进行相互的交流和检查. 02 设 ...

  9. hdu 1078 FatMouse and Cheese(记忆搜)

    N*N的矩阵,每个格子上有一个值. 老鼠起始在(1,1),每次只能水平着走或垂直着走.且最多只能走K步.且走到的格子里的值必须比上一次呆的格子里的值大. 问老鼠最多收集到多少值. 思路: 记忆搜好写. ...

  10. 面试官:熟悉JS中的new吗?能手写实现吗?

    目录 1 new 运算符简介 2 new 究竟干了什么事 3 模拟实现 new 运算符 4 补充 预备知识: 了解原型和原型链 了解this绑定 1 new 运算符简介 MDN文档:new 运算符创建 ...