听说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. C#:对字符串的各种处理

    字符串截取 SubString OR Remove string str3 = "123abc456"; //str3 = str3.Substring(0, i); //从左边开 ...

  2. from语法导入

    """# 在执行文件中能不能直接使用模块中的名字 # import m1# import m1 as m# print(m1.a)# print(m1.b)# print ...

  3. 借助FreeHttp任意篡改http报文 (使用·实现)

    引言 FreeHttp是一个Fiddler插件借助FreeHttp您可按照您自己的设定修改请求或响应报文,这对测试及调试都非常有用 比如您发现线上页面js文件错误,直接使用规则替换新的js文件您可以在 ...

  4. docker安装与测试 及 安装docker compose

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口 ...

  5. java 图片处理 base64编码和图片二进制编码相互转换

    今天在弄小程序项目时,涉及上传图片的更改. 以下是代码: /** * -> base64 * @param imgFile * @return * @throws IOException */ ...

  6. Echarts学习之路2(基本配置项)

    title:标题组件,包含主标题和副标题. title:{ text:"",//主标题 link:"",//主标题文本超链接 target:"&quo ...

  7. 浅拷贝(Shallow Copy) VS 深拷贝(Deep Copy)

    首先,深拷贝和浅拷贝针对的是对象类型(对象,数组,函数) 浅拷贝指的是只是拷贝了对象的引用地址,彼此之间高耦合,一个改变,另一个可能也随之改变: 深拷贝是指只是完整的将变量的值拷贝过来,是一个新的对象 ...

  8. bind:tap="onLike" 中不能添加参数 及 dataset 传值

    <view bind:tap="onLike({{id}})"></view> //Component "pages/book-detail/bo ...

  9. [算法]浅谈求n范围以内的质数(素数)

    汗颜,数学符号表达今天才学会呀-_-# 下面是百度百科对质数的定义 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 求质数的方法 ...

  10. 消息队列与Kafka

    2019-04-09 关键词: 消息队列.为什么使用消息队列.消息队列的好处.消息队列的意义.Kafka是什么 本篇文章系本人就当前所掌握的知识关于 消息队列 与 kafka 知识点的一些简要介绍,不 ...