算法一(50pts)

分析

有一个很显然的暴力做法,对于区间内的每个数开个bitset,然后暴力分解质因数。如果对于一个数,它的一个质因子的指数是奇数,那么就把bitset的对应位设成\(1\)。答案就是异或方程组解的个数,也就是\(2^{fail}\),\(fail\)表示向线性基插入失败的数的个数。

代码

#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
typedef std::bitset<175> Bitset;
using std::cin;
using std::cout;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MAXN=1005;
const LL MOD=998244353;
int L,R,cnt,prm[MAXN];
bool vis[MAXN]; void pre_process(int n){
rin(i,2,n){
if(!vis[i]) prm[++cnt]=i;
rin(j,1,cnt){
if(i*prm[j]>n) break;
vis[i*prm[j]]=true;
if(i%prm[j]==0) break;
}
}
} struct linear_basis{
Bitset a[175];int len,fail;
inline void clear(){
rin(i,0,len-1) a[i].reset();len=fail=0;
}
inline void insert(Bitset x){
if(!x.any()){++fail;return;}
irin(i,len-1,0){
if(!x[i]) continue;
if(!a[i].any()){a[i]=x;break;}
else{x^=a[i];if(!x.any()){++fail;return;}}
}
}
}basis; inline LL qpow(LL x,LL y){
LL ret=1,tt=x%MOD;
while(y){
if(y&1) ret=ret*tt%MOD;
tt=tt*tt%MOD;
y>>=1;
}
return ret;
} int main(){
pre_process(1000);
int T=read();
while(T--){
L=read(),R=read();basis.clear();
rin(i,L,R){
int x=i;Bitset temp;temp.reset();
rin(j,1,cnt){
if(x==1) break;
if(x%prm[j]) continue;
int r=0;
while(x%prm[j]==0) x/=prm[j],r^=1;
temp[j-1]=r;basis.len=std::max(basis.len,j);
if(x==1) break;
}
basis.insert(temp);
}
printf("%lld\n",qpow(2,basis.fail));
}
return 0;
}

算法二(100pts)

分析

一个显然的性质是对于任意正整数\(n\)最多只有一个大于\(\sqrt{n}\)的质因子(只有这个是我自己想到的ToT),所以我们可以在算法一的基础上,把这些\(>\sqrt{n}\)的质因子拿出来单独处理。对于每种质因子,取一个就好了,相当于把这个数的bitset强制插入线性基,并且这次插入必定成功,剩下的和这个数异或一下插入线性基。

但这样还是会TLE。有一个很玄学的优化,当\(R-L>6000\)时,可以认为每个质数都会单独被挂在线性基上而不是和其他质数一起,因此答案就是\(2^{R-L+1-cnt}\)(正确性不明)。

代码

#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
typedef std::bitset<455> Bitset;
using std::cin;
using std::cout;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MAXN=1e7+5;
const LL MOD=998244353;
int L,R,cnt,len,prm[MAXN],gp[MAXN],c[MAXN];
bool vis[MAXN]; void pre_process(int n){
rin(i,2,n){
if(!vis[i]) prm[++cnt]=i,gp[i]=i;
rin(j,1,cnt){
if(i*prm[j]>n) break;
vis[i*prm[j]]=true;
gp[i*prm[j]]=gp[i];
if(i%prm[j]==0) break;
}
}
} struct linear_basis{
Bitset a[452];int len,fail,siz;
inline void clear(){
rin(i,0,len-1) a[i].reset();len=fail=siz=0;
}
inline void insert(Bitset x){
if(siz==len||!x.any()){++fail;return;}
irin(i,len-1,0){
if(!x[i]) continue;
if(!a[i].any()){a[i]=x;++siz;break;}
else{x^=a[i];if(!x.any()){++fail;return;}}
}
}
}basis; inline LL qpow(LL x,LL y){
LL ret=1,tt=x%MOD;
while(y){
if(y&1) ret=ret*tt%MOD;
tt=tt*tt%MOD;
y>>=1;
}
return ret;
} inline bool cmp(int x,int y){
return gp[x]<gp[y];
} int main(){
pre_process(1e7);
int T=read();
while(T--){
L=read(),R=read();
if(R-L>6000){
int temp=0;
rin(i,1,cnt) if((L-1)/prm[i]<R/prm[i]) ++temp; else if(prm[i]>R) break;
printf("%lld\n",qpow(2,R-L+1-temp));
continue;
}
basis.clear();len=0;
rin(i,L,R) c[++len]=i; std::sort(c+1,c+len+1,cmp);
Bitset nowbasis;nowbasis.reset();
rin(i,1,len){
int x=c[i];Bitset temp;temp.reset();
if(gp[c[i]]<=3200){
rin(j,1,cnt){
if(x==1) break;
if(x%prm[j]) continue;
int r=0;
while(x%prm[j]==0) x/=prm[j],r^=1;
temp[j-1]=r;basis.len=std::max(basis.len,j);
if(x==1) break;
}
basis.insert(temp);
}
else if(i==1||gp[c[i]]!=gp[c[i-1]]){
x/=gp[x];
rin(j,1,cnt){
if(x==1) break;
if(x%prm[j]) continue;
int r=0;
while(x%prm[j]==0) x/=prm[j],r^=1;
temp[j-1]=r;basis.len=std::max(basis.len,j);
if(x==1) break;
}
nowbasis=temp;
}
else{
x/=gp[x];
rin(j,1,cnt){
if(x==1) break;
if(x%prm[j]) continue;
int r=0;
while(x%prm[j]==0) x/=prm[j],r^=1;
temp[j-1]=r;basis.len=std::max(basis.len,j);
if(x==1) break;
}
basis.insert(temp^nowbasis);
}
}
printf("%lld\n",qpow(2,basis.fail));
}
return 0;
}

[THUSC2017]杜老师:bitset+线性基的更多相关文章

  1. LOJ 2978 「THUSCH 2017」杜老师——bitset+线性基+结论

    题目:https://loj.ac/problem/2978 题解:https://www.cnblogs.com/Paul-Guderian/p/10248782.html 第 i 个数的 bits ...

  2. 洛谷 P7451 - [THUSCH2017] 杜老师(线性基+根分+结论题)

    题面传送门 看到乘积为平方数我们可以很自然地想到这道题,具体来说,我们对 \(1\sim 10^7\) 中所有质因子标号 \(1,2,\cdots,\pi(10^7)\),对于 \(x\in[l,r] ...

  3. 【THUSC2017】杜老师

    题目描述 杜老师可是要打+∞年World Final的男人,虽然规则不允许,但是可以改啊! 但是今年WF跟THUSC的时间这么近,所以他造了一个idea就扔下不管了…… 给定L,R,求从L到R的这R− ...

  4. 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)

    LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...

  5. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  6. BZOJ 1923 外星千足虫(bitset优化线性基)

    题意:给出m次n个千足虫的足数信息,确定在第几次测试后可以确定每个千足虫的来历. 我们可以观察到每个测试结果具有异或后依然成立的性质,于是实际上我们只需要从头到尾确定有n个线性相关的向量是在哪一个测试 ...

  7. Wannafly Winter Camp 2020 Day 5J Xor on Figures - 线性基,bitset

    有一个\(2^k\cdot 2^k\) 的全零矩阵 \(M\),给出 \(2^k\cdot 2^k\) 的 \(01\) 矩阵 \(F\),现在可以将 \(F\) 的左上角置于 \(M\) 的任一位置 ...

  8. 高斯消元 & 线性基【学习笔记】

    高斯消元 & 线性基 本来说不写了,但还是写点吧 [update 2017-02-18]现在发现真的有好多需要思考的地方,网上很多代码感觉都是错误的,虽然题目通过了 [update 2017- ...

  9. BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]

    2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...

随机推荐

  1. 打印输出opencv的版本信息

    本文链接: https://mangoroom.cn/opencv/print-opencv-version-info.html 序 查看自己安装的opencv的版本信息的方法有两种. 方法一-查看l ...

  2. 赛道修建 NOIP 2018 d1t3

    题目大意 最小值最大 考虑二分 二分答案 判断能不能构成m条路径 很明显满足单调性 可行 思考如何判断 对于一个节点 它的儿子会传上来一些路径 这些路径只有三种处理方式 一.传上去(只能传一条) 二. ...

  3. Python细节(二)小数据池

    3.8小数据池 python是由代码块构成的 代码块,一个模块.一个函数,一个类,一个文件,eval(),exec()执行的时候也是一个代码块 1.内存地址 id() 通过id() 我们可以查看到一个 ...

  4. 【优质blog、网址】置顶

    一.大公司等技术blog:   blog1: http://blog.csdn.net/mfcing/article/details/51577173 blog2: http://blog.csdn. ...

  5. 对Elastic集群内部配置TLS加密通信及身份验证

    1.介绍 官方宣布从6.8和7.1开始,免费提供多项安全功能.其中包括tls加密通信,基于角色访问控制等功能. 可以使用企业CA证书来完成这一步骤,但是一般情况下,我们可以通过elasticsearc ...

  6. 如何导入GitHub下的vue项目 并启动

    如何运行  下载的GitHub项目 一 准备工作: Node.js环境(npm包管理器) vue-cli 脚手架构建工具 cnpm npm的淘宝镜像 二 安装node.js 略 cmd 输入node ...

  7. 关于JAVA中的synchronized,一段不错的解释...

  8. flutter-dart语言初识

    dart 官方文档 http://dart.goodev.org/guides/language/language-tour# 重要概念所以能够使用变量引用的都是对象,也就是所以可以赋值给变量的都是对 ...

  9. 十三、LaTex中的参考文献BibTex

    将默认文献工具设置为bibtex

  10. iPad和iPhone上的应用程序图标

    iPad和iPhone上的应用程序图标 问:如何在iPad和iPhone使用我的应用程序包中的图标文件? 答:下面是处理文件的图标为iPhone专用的应用程序,iPad的专用应用程序,以及通用的应用程 ...