THUSC 2017 D1T2 杜老师
这是个非常有趣的数学题啦...
其实大概推一推式子就能得到一个信息,就是答案一定是$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 杜老师的更多相关文章
- LOJ #2978「THUSCH 2017」杜老师
听说LOJ传了THUSC题赶紧上去看一波 随便点了一题都不会做想了好久才会写暴力爆了一发过了... LOJ #2978 题意 $ T$次询问,每次询问$ L,R$,问有多少种选取区间中数的方案使得选出 ...
- loj#2978. 「THUSCH 2017」杜老师(乱搞)
题面 传送门 题解 感谢yx巨巨 如果一个数是完全平方数,那么它的所有质因子个数都是偶数 我们把每一个数分别维护它的每一个质因子的奇偶性,那么就是要我们选出若干个数使得所有质因子的个数为偶数.如果用线 ...
- LOJ 2978 「THUSCH 2017」杜老师——bitset+线性基+结论
题目:https://loj.ac/problem/2978 题解:https://www.cnblogs.com/Paul-Guderian/p/10248782.html 第 i 个数的 bits ...
- 【THUSC2017】杜老师
题目描述 杜老师可是要打+∞年World Final的男人,虽然规则不允许,但是可以改啊! 但是今年WF跟THUSC的时间这么近,所以他造了一个idea就扔下不管了…… 给定L,R,求从L到R的这R− ...
- THUSC 2017 游记
Day0 早上在家里整理东西. 下午坐飞机去北京.(怎么又去北京,上周刚去的北京) 一开始飞机爬升的时候太无聊就睡着了.醒了以后就开始吃东西.吐槽一句:厦航的飞机就是好啊.上面的点心也比上次海航的好吃 ...
- 【THUSC2017】【LOJ2978】杜老师 高斯消元
题目大意 给你 \(l,r\),求从 \(l\) 到 \(r\) 这 \(r-l+1\) 个数中能选出多少个不同的子集,满足子集中所有的数的乘积是一个完全平方数. 对 \(998244353\) 取模 ...
- 洛谷 P4948 拉格朗日多项式插值(杜老师板子)
https://www.luogu.org/problemnew/show/P4948 这篇博客主要目的是存一下的dls的神奇板子,本来应该是推公式或者二分做的 但是dls的插值板子直接写好了这个特殊 ...
- 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 ...
- [THUSC2017]杜老师:bitset+线性基
算法一(50pts) 分析 有一个很显然的暴力做法,对于区间内的每个数开个bitset,然后暴力分解质因数.如果对于一个数,它的一个质因子的指数是奇数,那么就把bitset的对应位设成\(1\).答案 ...
随机推荐
- tinyint、smallint、bigint、int 区别
1byte=8bit [tinyint] 从 0 到 255 的整型数据.存储大小为 1 字节.如果设置为UNSIGNED类型,只能存储从0到255的整数,不能用来储存负数. [smallint] ...
- 修复vs2012出现 “无法找到包源”的错误
出现以上问题,需要去“控制面板”添加程序,找到vs2012右键“修改” 用来安装 web Developer 如下图所示: 点击继续
- 网络基础 利用vnc viewer访问在vmware虚拟机上的linux
利用vnc viewer访问在vmware虚拟机上的linux by:授客 QQ:1033553122 Linux服务器为架设在VMware之上的虚拟机,那么可以直接使用VMware自带的vnc,而不 ...
- Android 外部启动activity,自定义action,action常量大全
从任意app,启动另外一个app的activity: 1. Intent i = new Intent(); ComponentName cn = new ComponentN ...
- 【Kibana】Kibana入门教程
一.Kibana简介及下载安装 Kibana是专门用来为ElasticSearch设计开发的,可以提供数据查询,数据可视化等功能. 下载地址为:https://www.elastic.co/downl ...
- Expo大作战(十九)--expo打包后,发布分用程序到商店的注意事项
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- Chrome下解决本地异步请求失败的问题(Origin null is not allowed by Access-Control-Allow-Origin. )
Chrome更新版本后发现打开本地Jquery easyui没有数据,查看控制台才发现如下问题解决的办法是设置启动参数"--allow-file-access-from-files" ...
- Jemeter 连接数据库
1.打开Jmeter添加测试计划,(http://central.maven.org/maven2/mysql/mysql-connector-java/6.0.6/mysql-connector-j ...
- 控制台输出 mybatis 中的sql语句
控制台输出 mybatis 中的sql语句 在 log4j.xml 文件中 增加如下配置 <!-- mybatis 输出的sql,DEBUG级别 --> <logger name=& ...
- 如何在 Azure 中标记 Windows 虚拟机
本文介绍在 Azure 中通过 Azure 资源管理器标记 Windows 虚拟机的不同方式.标记是用户定义的键/值对,可直接放置在资源或资源组中.针对每个资源和资源组,Azure 当前支持最多 15 ...