当前位置: 首页 > news >正文

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));
	}
}

  

转载于:https://www.cnblogs.com/Winniechen/p/10163795.html

相关文章:

  • JAVA企业级应用TOMCAT实战
  • 数据可视化之 Sankey 桑基图的实现
  • 前端面试题总结
  • VUE es6技巧写法(持续更新中~~~)
  • 用jquery写贪吃蛇
  • 解析Vue-router相关基础知识及工作原理
  • 订单的业务流程
  • 序列化与反序列化
  • java~@Async异步功能
  • 给Prometheus造假数据的方法
  • [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
  • java Concurrent包学习笔记(六):Exchanger
  • 理解 Web 中的Session
  • bzoj3295: [Cqoi2011]动态逆序对
  • 北大、微软提出NGra:高效大规模图神经网络计算
  • Android 架构优化~MVP 架构改造
  • C++类中的特殊成员函数
  • Docker入门(二) - Dockerfile
  • ES6系统学习----从Apollo Client看解构赋值
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • JS学习笔记——闭包
  • PHP面试之三:MySQL数据库
  • Redis在Web项目中的应用与实践
  • Travix是如何部署应用程序到Kubernetes上的
  • vue-cli在webpack的配置文件探究
  • vue总结
  • 阿里云Kubernetes容器服务上体验Knative
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 因为阿里,他们成了“杭漂”
  • 用 Swift 编写面向协议的视图
  • 自动记录MySQL慢查询快照脚本
  • puppet连载22:define用法
  • 树莓派用上kodexplorer也能玩成私有网盘
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • $.ajax()方法详解
  • (1) caustics\
  • (Java)【深基9.例1】选举学生会
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)Linux下编译安装log4cxx
  • (转)Unity3DUnity3D在android下调试
  • (转)程序员技术练级攻略
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .NET Core WebAPI中封装Swagger配置
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET构架之我见
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • /etc/skel 目录作用
  • @EventListener注解使用说明
  • @我的前任是个极品 微博分析
  • [ACTF2020 新生赛]Upload 1