算法一(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 boot-14.集成MyBatis

    1.如何使用注解版Mybatis? (1)引入mybatis ,druid,Mysql 的依赖,环境搭建可以参考第13篇的内容 <dependency> <groupId>or ...

  2. Thread 线程 1

    Thread 常用方法: String getName() 返回该线程的名称. void setName(String name) 改变线程名称,使之与参数 name 相同. int getPrior ...

  3. MD5算法+盐Salt

    1.MD算法的基的概念    MD5算法是典型的消息摘要算法,其前身有MD2.MD3和MD4算法,它由MD4.MD3和MD2算法改进而来.不论是哪一种MD算法,它们都需 要获得一个随机长度的信息并产生 ...

  4. Berland Army CodeForces - 883B (贪心,拓扑排序)

    大意: n个点, 点$i$的等级为$r_i$, 只给出部分点的$r$值, $r_i$的范围为[1,k], 且[1,k]都至少有一个. 给定m条有向边, (x,y)表示$r[x]>r[y]$, 求 ...

  5. maven配置生成可执行的jar:maven-shade-plugin

    默认打包生成的jar是不能直接运行的,因为带有main方法的信息不会添加到mainifest中,需要借助maven-shade-plugin <project> ... <build ...

  6. Java学习:identityHashCode和hashCode方法

    System类提供了一个identityHashCode(Object x)方法,这个方法返回的是指定对象的精确hashCode值,也就是根据该对象的地址计算得到的hashCode值. 当某个类的ha ...

  7. java复习(2)

    1.函数的重载:在同一个类中,允许存在一个以上的同名函数,只要他们的参数个数或者参数类型不相同就可以. 重载与返回值类型无关,只看参数列表.重载方便阅读,优化了程序的设计 eg://返回两个 整数值的 ...

  8. help_topic表,以字符拆分,一行转多行

      help_topic表是数据库mysql下的一个表        SUBSTRING_INDEX(s, delimiter, number)        返回从字符串 s 的第 number 个 ...

  9. 在centOS7.2上编译gcc4.1.2

    1.下载安装gcc4.1.2安装包  wget ftp://ftp.gnu.org/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2 注:其他版本的安装包可以在上级目录寻找到. ...

  10. Ansible批量部署工具

    Ansible:自动化运维工具 你需要在一台机器上yum install 一个包,这时候有一个需求,比如现在有5台机同时需要装apache这个包,那么100台呢,ssh上去就太慢了,这时候就借助到了a ...