LOJ #2978「THUSCH 2017」杜老师
听说LOJ传了THUSC题赶紧上去看一波
随便点了一题都不会做想了好久才会写暴力爆了一发过了...
题意
$ 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」杜老师的更多相关文章
- LOJ 2978 「THUSCH 2017」杜老师——bitset+线性基+结论
题目:https://loj.ac/problem/2978 题解:https://www.cnblogs.com/Paul-Guderian/p/10248782.html 第 i 个数的 bits ...
- loj#2978. 「THUSCH 2017」杜老师(乱搞)
题面 传送门 题解 感谢yx巨巨 如果一个数是完全平方数,那么它的所有质因子个数都是偶数 我们把每一个数分别维护它的每一个质因子的奇偶性,那么就是要我们选出若干个数使得所有质因子的个数为偶数.如果用线 ...
- @loj - 2977@ 「THUSCH 2017」巧克力
目录 @description@ @solution@ @accepted code@ @details@ @description@ 「人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道.」 明 ...
- LOJ 2980 「THUSCH 2017」大魔法师——线段树
题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...
- LOJ 2979 「THUSCH 2017」换桌——多路增广费用流
题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...
- LOJ 2997 「THUSCH 2017」巧克力——思路+随机化+斯坦纳树
题目:https://loj.ac/problem/2977 想到斯坦纳树.但以为只能做 “包含一些点” 而不是 “包含一些颜色” .而且不太会处理中位数. 其实 “包含一些颜色” 用斯坦纳树做也和普 ...
- LOJ#2977. 「THUSCH 2017」巧克力(斯坦纳树+随机化)
题目 题目 做法 考虑部分数据(颜色较少)的: 二分中位数\(mid\),将\(v[i]=1000+(v[i]>mid)\) 具体二分操作:然后求出包含\(K\)种颜色的联通快最小的权值和,判断 ...
- 「THUSCH 2017」大魔法师 解题报告
「THUSCH 2017」大魔法师 狗体面太长,帖链接了 思路,维护一个\(1\times 4\)的答案向量表示\(A,B,C,len\),最后一个表示线段树上区间长度,然后每次的操作都有一个转移矩阵 ...
- LOJ 2288「THUWC 2017」大葱的神力
LOJ 2288「THUWC 2017」大葱的神力 Link Solution 比较水的提交答案题了吧 第一个点爆搜 第二个点爆搜+剪枝,我的剪枝就是先算出 \(mx[i]\) 表示选取第 \(i \ ...
随机推荐
- python学习笔记2_条件循环和其他语句
一.条件循环和其他语句 1.print和import的更多信息. 1.1.使用逗号输出 //print() 打印多个表达式是可行的,用逗号隔开. 在脚本中,两个print语句想在一行输出 ...
- UOJ #449. 【集训队作业2018】喂鸽子
UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
- 【题解】P2922 [USACO08DEC]秘密消息Secret Message
\(\text{Tags}\) 字典树,统计 题意: 给出两组\(\text{0/1}\)串\(\text{A,B}\),求解\(\text{A}\)中某串是\(\text{B}\)中某串的前缀,和\ ...
- 菜鸟学IT之python网页爬取初体验
作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2881 1. 简单说明爬虫原理 爬虫简单来说就是通过程序模拟浏览器放松请求站 ...
- C#关于TreeView树在节点数较多时总是会出现闪烁的问题方法记录
首先介绍下背景吧,问题如题,这个问题应该说困扰我大半年了(不是说我没有请教大佬,不是说我没有上网查过,之前在搜索时,总是没有解决此问题~~),直到最近一次在在优化代码时,再次上网查找,在发现搜索词条” ...
- sql 语句中as的用法和作用
我们的Sql语句在很多数据库中都是通用的,比如像Mysql数据库 Access数据库. Oracle数据库. Sqlite数据库 .甚至在我们的Excel中也可以使用Sql语句. 在我的数据库中有u ...
- ueditor 回显html样式会直接出来,无效
百度了好久,后面发现可以直接这样
- 【python 字符串】 字符串的相关方法(一)
将字符串首字母变为大写 -> capitalize() 方法 # 将字符串的首字母转换为大写 text = 'alet' ret = text.capitalize() print(ret) ...
- Gym - 101982F Rectangles (扫描线+线段树)
链接:http://codeforces.com/gym/101982/attachments 思路: 问被覆盖次数为奇数次的矩阵的面积并 扫描线求矩阵面积并我们是上界赋为-1,下界赋为1,因为要求覆 ...
- 最简单的JAVA解析XML字符串方法
引入 dom4j 包<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifa ...