这是个非常有趣的数学题啦...

其实大概推一推式子就能得到一个信息,就是答案一定是$2$的整数次幂,并且其实答案就是$2^{R-L+1-sum}$,其中$sum$表示有多少个数不能用$L-i-1$的数表达出来。

另外,根据寿司晚宴那道题给予的启发,我们只需要统计质数小于$\sqrt {10^7}$的就可以了,然后打一个表就可以知道,一共大概有$450$个左右。

那么$70$分的部分分就很容易到手了。

我们可以通过$O(n)$的时间复杂度,预处理出$10^7$以内的所有数的最大质因子,显然,每个数大于$\sqrt{10^7}$的质因子最多只有一个。

那么可以分开考虑,如果没有大于$\sqrt{10^7}$的质因子,那么就可以用$bitset$维护一下每个质因子在选取的同时需要选择哪些其他比他大的质因子,以及现在需要选择什么质因子。

然后还有就是需要把所有的在$[L,R]$之内的数,按照最大质因子的大小排序,这样是为了保证在更新到$x$的时候,比$x$小的质因子都已经出现过了,或者不会再出现了,或者出现的时候再来更新答案。

然后每次$O(\frac{450\times 450}{32})$的时间(跑不满,大概均摊下来每次询问的总时间是$O(\frac{450^3}{32})$上下的),来验证能否更新答案,也就是能否被选出了更新答案,具体实现类似高斯消元。

然后如果存在比$\sqrt{10^7}$大的质因子,那么就把这个质因子去掉。

如果没存在过这个质因子,那么把这个数能分解出来的小于$\sqrt{10^7}$的质因子全部记录下来,并且这个数不能用来更新答案。

如果存在过这个质因子,那么上面一定处理过了上一个包含这个质因子的数的小于$\sqrt{10^7}$的质因子,然后用两个$bitset$抑或一下,也就是说这个质因子必须被消掉,然后再重复进行最上面没有大于$\sqrt{10^7}$的质因子的操作即可。

然后这个东西的正确性显然,因为其实所有包含数$x$的能成为完全平方数的方案都是同构的,也就是从某个方案加上一个乘积是完全平方数的方案转移过来的,所有只需要验证一个方案能否满足即可,也就是说能不能通过前面某些不同的质因子把相同的东西完全消去。

这个是$70$分的东西,因为算上排序等操作,一次询问的总时间复杂度是$O(\frac{450^3}{32}+(R-L+1)\log {(R-L+1)}+(R-L+1)\times \frac{500}{32})$的。

这个东西完全没有办法优化了...

然后可以通过一些奇思妙想拿到满分。(其实只需要加上$11,12$测试点的特判就可以了...)

也就是说,如果$R-L+1$的区间大于$2\times \sqrt{10^7}$的话,就会在这段区间内包含全部的$1\sim \sqrt{10^7}$以内的所有质因子,通过消元的话,一定可以得到全部的数字,除非这个数的是质数,并且只在这点区间内只出现一次。

具体证明的话,我也不会很会啊...(因为我复现的时候才写了$70$分啊)

然后就没了...

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
using namespace std;
#define N 10000005
#define ll long long
#define mod 998244353
struct node
{
int x,y;
node(){}
node(int a,int b){x=a,y=b;}
inline bool operator < (const node &a) const {return y==a.y?x<a.x:y<a.y;}
}a[N];
bitset<455>b[455],now,tmp;
int ans,L,R,pri[N],t[N],vis[N],idx[N],cnt,tot,block,size;bool f[N];
void init()
{
t[1]=1;
for(int i=2;i<=10000000;i++)
{
if(!vis[i])pri[++cnt]=i,t[i]=i,idx[i]=cnt,size+=(i<=block);
for(int j=1;j<=cnt&&pri[j]*i<=10000000;j++)
{
vis[pri[j]*i]=1;t[pri[j]*i]=max(pri[j],t[i]);
if(i%pri[j]==0)break;
}
}
}
int get_fac(int x,bitset<455> &now)
{
bool flag=0;now.reset();
if(t[x]>block)x/=t[x];
while(x!=1)
{
int j=t[x],cnt=0;
while(x%j==0)x/=j,cnt++;
if(cnt&1)
{
now[idx[j]]=1;
flag=1;
}
}return flag;
}
int get_now()
{
for(int i=1;i<=size;i++)
if(now[i])
if(b[i][i])now^=b[i];
else return b[i]=now,1;
return 0;
}
int q_pow(int x,int n){int ret=1;for(;n;n>>=1,x=(ll)x*x%mod)if(n&1)ret=(ll)ret*x%mod;return ret;}
int solve(int L,int R)
{
int ret1=0,ret2=0;tot=0;
for(int i=max(2,L);i<=R;i++)a[++tot]=node(i,t[i]);
sort(a+1,a+tot+1);
for(int i=1;i<=size;i++)b[i].reset();
for(int i=1;i<=tot;i++)
{
if(a[i].y<=block)
{
if(ret1<=size)
if(get_fac(a[i].x,now))
ret1+=get_now();
}else if(a[i].y!=a[i-1].y)
{
ret2++;
if(ret1<=size)get_fac(a[i].x,tmp);
}else if(ret1<=size)
{
get_fac(a[i].x,now);
now^=tmp;ret1+=get_now();
}
}
return q_pow(2,R-L+1-ret1-ret2);
}
int solve2(int L,int R)
{
int ret=0;
for(int i=2;i<=R;i++)
if(!vis[i]&&(R/i)>((L-1)/i))ret++;
return q_pow(2,R-L+1-ret);
}
int main()
{
block=sqrt(10000000)+1;
int T;scanf("%d",&T);init();
while(T--)
{
scanf("%d%d",&L,&R);
if(R-L<=100000)printf("%d\n",solve(L,R));
else printf("%d\n",solve2(L,R));
}
}

  

THUSC 2017 D1T2 杜老师的更多相关文章

  1. LOJ #2978「THUSCH 2017」杜老师

    听说LOJ传了THUSC题赶紧上去看一波 随便点了一题都不会做想了好久才会写暴力爆了一发过了... LOJ #2978 题意 $ T$次询问,每次询问$ L,R$,问有多少种选取区间中数的方案使得选出 ...

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

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

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

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

  4. 【THUSC2017】杜老师

    题目描述 杜老师可是要打+∞年World Final的男人,虽然规则不允许,但是可以改啊! 但是今年WF跟THUSC的时间这么近,所以他造了一个idea就扔下不管了…… 给定L,R,求从L到R的这R− ...

  5. THUSC 2017 游记

    Day0 早上在家里整理东西. 下午坐飞机去北京.(怎么又去北京,上周刚去的北京) 一开始飞机爬升的时候太无聊就睡着了.醒了以后就开始吃东西.吐槽一句:厦航的飞机就是好啊.上面的点心也比上次海航的好吃 ...

  6. 【THUSC2017】【LOJ2978】杜老师 高斯消元

    题目大意 给你 \(l,r\),求从 \(l\) 到 \(r\) 这 \(r-l+1\) 个数中能选出多少个不同的子集,满足子集中所有的数的乘积是一个完全平方数. 对 \(998244353\) 取模 ...

  7. 洛谷 P4948 拉格朗日多项式插值(杜老师板子)

    https://www.luogu.org/problemnew/show/P4948 这篇博客主要目的是存一下的dls的神奇板子,本来应该是推公式或者二分做的 但是dls的插值板子直接写好了这个特殊 ...

  8. THUSC 2017 大魔法师

    一个序列,每个物品有三个权值 $A,B,C$ 要求维护: 1.区间 $A_i+=B_i$ 2.区间 $B_i+=C_i$ 3.区间 $C_i+=A_i$ 4.区间 $A_i+=v$ 5.区间 $B_i ...

  9. [THUSC2017]杜老师:bitset+线性基

    算法一(50pts) 分析 有一个很显然的暴力做法,对于区间内的每个数开个bitset,然后暴力分解质因数.如果对于一个数,它的一个质因子的指数是奇数,那么就把bitset的对应位设成\(1\).答案 ...

随机推荐

  1. bootstrap datetimepicker日期插件美化

    效果 https://segmentfault.com/img/bVbieIp?w=1029&h=461 原文链接:https://segmentfault.com/a/11900000167 ...

  2. 如何在Vue中建立全局引用或者全局命令

    1 一般在vue中,有很多vue组件,这些组件每个都是一个文件.都可能需要引用到相同模块(或者插件).我们不想每个文件都import 一次模块. 如果是基于vue.js编写的插件我们可以用 Vue.u ...

  3. windows 服务的安装与卸载

    卸载服务 Cmd 执行 Sc delete axXinkong(服务名称) 安装服务

  4. Android--仿一号店货物详情轮播图动画效果

    还不是很完全,目前只能点中间图片才能位移,图片外的其他区域没有..(属性动画),对了,图片加载用得是facebook的一款android图片加载库,感觉非常NB啊,完爆一切. 1.先看布局 <? ...

  5. Expo大作战(三)--针对已经开发过react native项目开发人员有针对性的介绍了expo,expo的局限性,开发时项目选型注意点等

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  6. [zz]VC2005-应用程序正常初始化失败-0xc0150002

    最近几天被这个问题困惑了许久. 不禁感叹微软的东东真是越做越烂了,也终于明白了时隔12年大家仍然死守VC6的原因.. 用VC2005编译的程序,编译时没有任何错误,但是运行时就是提示“应用程序正常初始 ...

  7. QT学习2

    一.常用控件与常用的功能函数.  QDialog.QMainWindow.QPushButton.QLabel.QLineEdit 构造函数指定父容器.setText,getText,size,res ...

  8. Java语言的主要特点

    Java语言有很多的优点,可靠.安全.编译和解释型语言.分布式.多线程.完全面向对象.与平台无关性等等. 与平台无关性 Java语言最大的优势在于与平台无关性,也就是可以跨平台使用. 绝大多数的编程语 ...

  9. 【转】Java学习---Java核心数据结构(List,Map,Set)使用技巧与优化

    [原文]https://www.toutiao.com/i6594587397101453827/ Java核心数据结构(List,Map,Set)使用技巧与优化 JDK提供了一组主要的数据结构实现, ...

  10. MySQL基础之 标准模式通配符

    MySQL标准魔兽通配符 作用:在搜索数据库中的数据时,SQL通配符可以替代一个或多个字符 注意:标准模式SQL通配符必须与LIKE运算符一起使用 1.%  通配符 作用:匹配一个或多个字符. 找出以 ...