算法一(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. Spring JdbcTemplate 和 NamedParameterJdbcTemplate 使用

    1.简单介绍 DAO层 的一般使用常见的是MyBatis 和 Hibernate,但是Hibernate是重量级的,而且学习成本较高,Mybatis 需要编写大量配置文件及接口文件,对于简单的项目应用 ...

  2. 手写数字识别 卷积神经网络 Pytorch框架实现

    MNIST 手写数字识别 卷积神经网络 Pytorch框架 谨此纪念刚入门的我在卷积神经网络上面的摸爬滚打 说明 下面代码是使用pytorch来实现的LeNet,可以正常运行测试,自己添加了一些注释, ...

  3. Luogu P2612 [ZJOI2012]波浪

    题目 我们考虑从\(1\)到\(n\)把每个数放到序列里面去,以消掉绝对值. 在最后的序列中,如果\(i\)的某一边是序列的边界,那么\(i\)会产生\(0\)的贡献.如果\(i\)的某一边是一个比\ ...

  4. tp5框架用foreach循环时候报Indirect modification of overloaded element of think\paginator\driver\Bootst错误

    thinkphp5使用paginator分页查询数据后,需要foreach便利处理某一字段的数据,会出现类似题目的错误.主要是因为tp5使用分页类读取的数据不是纯数组的格式!所以在循环的时候需要用数据 ...

  5. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  6. IBM小机拆镜像换盘

    1.硬盘告警信息     2.故障排查 查看错误日志 #  errpt   -aj   C62E1EB7     查看hdisk0的信息,发现hdisk0属于rootvg # lspv   查看hdi ...

  7. 机器学习五 EM 算法

    目录 引言 经典示例 EM算法 GMM 推导 参考文献: 引言 Expectation maximization (EM) 算法是一种非常神奇而强大的算法. EM算法于 1977年 由Dempster ...

  8. linux就该这么学.pdf

    链接:https://pan.baidu.com/s/1mhYIqgg 密码:ay0j

  9. 分布式配置中心(Spring Cloud Config) (问题解答)

    转载:https://blog.csdn.net/forezp/article/details/70037291 1.foo是博主随意写的,实际是没有对应的文件.如果真有文件,返回的json在会有so ...

  10. Xshell6-项目使用

    前端开发中,涉及服务器的地方一般都交给后端处理,这样有时候很不方便,所以,自己来上传服务器是非常爽的啦 工具: Xshell6 传送门: http://www.netsarang.com/produc ...