听说LOJ传了THUSC题赶紧上去看一波

随便点了一题都不会做想了好久才会写暴力爆了一发过了...

LOJ #2978


题意

$ T$次询问,每次询问$ L,R$,问有多少种选取区间中数的方案使得选出的数的积为完全平方数

$ T \leq 100,R \leq 10^7 \sum\limits R-L \leq 6·10^7$

时限$ 5s$


题解

随便写个暴力发现答案都是$2$的若干次幂

首先对于每个数,每个质因子出现的次数显然只有奇偶性是有用的

用一个$ bitset$存储每个数中每个质因数的出现次数的奇偶性

则问题转化成取若干个数使得异或和为$ 0$

用线性基维护这个问题

答案则为$ 2^{自由基的数量}$

其中自由基就是可以被其他基所表示的基

直接这么暴力复杂度太大

考虑若一个质因数的平方超过$ 10^7$那它不可能在一个数中出现两次

因此我们只统计前$ \sqrt{10^7}$个数中的质因数(446个)的$ bitset$

统计答案的时候我们先将区间内数按其最大质因数排序(若一个数的最大质因数不超过 $\sqrt{10^7}$则认为是0)

对于一段最大质因数相同的区间,我们钦定第一个数为非自由基

则这段区间的其他拥有这个质因数的数可以异或上这个钦定的非自由基

以起到消掉这个额外质因数的效果

这样暴力做的复杂度是$ O(6·10^7·450·\frac{450}{64})$的

显然过不了

如果加个剪枝:若当前线性基已满则直接跳出判断 就能过了...

虽然跑的超级慢...

这题有个科技:

若$ R-L+1$超过了一个定值(可定为$ 2 \sqrt{10^7}$),则对每个质数,我们只要选一个数作为这个数的基底

然后所有其他非基底的区间中的数都能被这些基底表示

即答案为$ 2^{R-L+1-出现过的质数数量}$

然后就跑的飞快了...


代码

去掉Solve就是暴力

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<bitset>
#define p 998244353
#define file(x)freopen(x".in","r",stdin);freopen(x".out","w",stdout)
#define rt register int
#define l putchar('\n')
#define ll long long
#define r read()
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans,val=;
bool pri[];int ss[],id[],lp[],zs[],tot;
bitset<>a[];
int q[],sl;
bitset<>make(int x){
bitset<>A;
if(lp[x])x/=lp[x];
for(rt i=;ss[i]*ss[i]<=x&&i<=cnt;i++)while(x%ss[i]==)
A.flip(i),x/=ss[i];
if(x>)A.flip(id[x]);
return A;
}
vector<int>jw[];
void solve(int L,int R){
int gs=R-L+;
for(rt i=;i<=tot&&zs[i]<=R;i++)if(R/zs[i]!=(L-)/zs[i])gs--;
int ans=;
for(rt x=,i=gs;i;i>>=,x=1ll*x*x%p)if(i&)
ans=1ll*ans*x%p;writeln(ans);
}
int main(){
n=r;if(n<=)val=;
const int v=sqrt(val);
for(rt i=;i<=val;i++)if(!pri[i]){
if(i<=v)ss[++cnt]=i,id[i]=cnt;
zs[++tot]=i;
if(i<=v)for(rt j=i*i;j<=val;j+=i)pri[j]=;
if(i>v)for(rt j=i;j<=val;j+=i)lp[j]=i;
}
bitset<>now;
while(n--){
memset(a,,sizeof(a));
int L=r,R=r,ans=;int len=;
if(R-L>){
solve(L,R);
continue;
}
for(rt i=L;i<=R;i++)if(lp[i]<=)jw[lp[i]].push_back(i);
for(rt i=L;i<=R;i++)if(lp[i]<=){
for(rt j=;j<jw[lp[i]].size();j++)q[++len]=jw[lp[i]][j];
jw[lp[i]].clear();
}
sl=;now&=;
for(rt i=;i<=len;i++){
const int v=q[i];
if(lp[v]!=lp[q[i-]]&&i>)now=make(v);
else {
if(sl==cnt){ans=1ll*ans*%p;continue;}
bitset<>g=make(v)^now;
if(g.count()==){ans=1ll*ans*%p;continue;}
for(rt j=;j>=;j--)if(g[j]){
if(a[j][j]){
if(g==a[j]){ans=1ll*ans*%p;break;}
g^=a[j];
}
else {a[j]=g;sl++;break;}
}
}
}
writeln(ans);
}
return ;
}

LOJ #2978「THUSCH 2017」杜老师的更多相关文章

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

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

  2. loj#2978. 「THUSCH 2017」杜老师(乱搞)

    题面 传送门 题解 感谢yx巨巨 如果一个数是完全平方数,那么它的所有质因子个数都是偶数 我们把每一个数分别维护它的每一个质因子的奇偶性,那么就是要我们选出若干个数使得所有质因子的个数为偶数.如果用线 ...

  3. @loj - 2977@ 「THUSCH 2017」巧克力

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 「人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道.」 明 ...

  4. LOJ 2980 「THUSCH 2017」大魔法师——线段树

    题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...

  5. LOJ 2979 「THUSCH 2017」换桌——多路增广费用流

    题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...

  6. LOJ 2997 「THUSCH 2017」巧克力——思路+随机化+斯坦纳树

    题目:https://loj.ac/problem/2977 想到斯坦纳树.但以为只能做 “包含一些点” 而不是 “包含一些颜色” .而且不太会处理中位数. 其实 “包含一些颜色” 用斯坦纳树做也和普 ...

  7. LOJ#2977. 「THUSCH 2017」巧克力(斯坦纳树+随机化)

    题目 题目 做法 考虑部分数据(颜色较少)的: 二分中位数\(mid\),将\(v[i]=1000+(v[i]>mid)\) 具体二分操作:然后求出包含\(K\)种颜色的联通快最小的权值和,判断 ...

  8. 「THUSCH 2017」大魔法师 解题报告

    「THUSCH 2017」大魔法师 狗体面太长,帖链接了 思路,维护一个\(1\times 4\)的答案向量表示\(A,B,C,len\),最后一个表示线段树上区间长度,然后每次的操作都有一个转移矩阵 ...

  9. LOJ 2288「THUWC 2017」大葱的神力

    LOJ 2288「THUWC 2017」大葱的神力 Link Solution 比较水的提交答案题了吧 第一个点爆搜 第二个点爆搜+剪枝,我的剪枝就是先算出 \(mx[i]\) 表示选取第 \(i \ ...

随机推荐

  1. Linux 下查看字体

    1.查看所有字体 命令:fc-list 2.查看中文字体 命令:fc-list :lang=zh 3.查看更多字体 命令:fc-match -v "AR PL UKai CN"

  2. Navicat 进行数据库自动备份

    今天经历一次数据库丢库事件,顿时觉得定时备份数据库很重要. 但是每天自己手动备份实在是太麻烦了,于是乎,想到用计划任务进行每天定时自动备份. 发现Navicat自带就有备份  还可以直接计划任务,贼方 ...

  3. python 提取pdf文字

    安装pdfminer 库 windows 下安装pdfminer3k pip install pdfminer3k Liunx 下安装pdfminer pip install pdfminer 代码 ...

  4. echarts 配置

    堆叠柱状图, 只要保证 stack 属性相同,就强制画成一列 这就是切割线

  5. CentOS7桌面版系统使用的一些小技巧

    1. 清空~/.kde/ 文件下的文件,登陆后不显示桌面的解决方法 在使用CentOS7 桌面系统时,有时候打开文件会很卡.这时我们需要清空当前用户下的 .kde 文件下的所有文件. 再重新登陆该用户 ...

  6. 17年iPhone炫酷铃声,mp3、m4r格式下载

    下载链接: https://pan.baidu.com/s/11aj9dBm9upNWpE5jWBgYog

  7. Sass和less的区别是什么?用哪个好

    什么是Sass和Less?       Sass和Less都属于CSS预处理器,那什么是 CSS 预处理器呢?        CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 ...

  8. 【BZOJ4013】[HNOI2015]实验比较(动态规划)

    [BZOJ4013][HNOI2015]实验比较(动态规划) 题面 BZOJ 洛谷 题解 看题目意思就是给你一棵树,连边表示强制顺序关系.然后你要给点染色,在满足顺序关系的情况下,将序列染成若干个颜色 ...

  9. go实现dgraph的各种操作

    go实现dgraph的各种操作 import "github.com/dgraph-io/dgo" import "github.com/dgraph-io/dgo/pr ...

  10. 我眼中的Adaboost

    步骤: def buildStump(dataArr,classLabels,D): 1.循环取出数据集中的一个特征(一列)输入 (for:) 2.循环调整阀值threshVal  (for:) 3, ...