这个题目巨坑啊。调试的时间加起来绝对超过1天整。

不过终于调试出来了,真心感动地尿流满面啊。

题目的意思是给你一个区间[A,B],可以从区间里选出任意多个整数,使得这些整数的积是一个不超过 2^126的 平方数。

比赛的时候的想法就基本和题解差不多了,但是依然没有能够A出来。神坑啊。

知道现在才搞定。

首先我们可以知道这个区间的右端点不超过4900,在1-4900里面有70个平方数。所以只要给定的区间包含了一个或多个平方数,我们直接输出最小的那个平方数就可以了哦。这样我们可以保证区间的长度小于139。

但是我们仍然无法圆满地解决这个问题,因为2^138依然是一个巨大的数字,时间和空间都是无法承受的。

再想优化的办法。我们可以发现,有的数字是一定不能选的,那就是区间里仅被含有一次的素数因子,因为只要你选了这个数,无论你接下来怎么选择,都无法凑成一个平方数。(但是值得注意的是,如果区间的一个数含有独特的因子,但是其含有的是该素数因子的平凡的话,也不能被筛去,我就是这里Wa出翔了)

这样我们可以发现我们可以把可选的数字的个数降低到不超过50。

接下来还有最后一个优化,题目里面说过最后的那个平方根不会超过2^63,这样等于是那个平凡数不会超过2^126,这样我们应该选择的数的个数就只有12个左右了。

(可以这样理解,前面的平方数之间的距离比较窄,所以个数不会多;后面的平方数之间距离虽然比较宽,但是本身比较大,所以也不会选择太多,这样考虑就知道了所有的个数不超过12个咯)。

有了这个我们就可以逐步枚举所有的组合情况了,(注意从个数少的枚举到个数多的,同时注意数小的数要先进行判定,这样保证找到的第一个可行解是最小解——这里题解写的是要用单调队列优化,但是我是这样做的,先保存所有选择一个的情况,然后判断并且由此推出所有选择两个的情况 ,每次对于当前因子数的所有数都处理完成后,对下面一列进行一次排序就好了——单调队列不会写T_T 。这样就保证了第一次找到的解是最小解了。)

其实在实现的过程中有好多的小细节,比如位运算的时候,1要写成(ll)1,不然就等着爆吧。还有对于两种组合后积大小的比较我是依靠一个double来比较的,个人认为这个方法略怂,但是还挺管用,嘿嘿。

详细的就见代码吧!

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define ll unsigned long long
#define maxQ 1000000//理论上来说要开的大一些
#define maxn 4920
using namespace std; struct node{
double tot;
ll id;
}cur,p; vector<int> vet[maxn+]; int prim[maxn+],f1[maxn+],Pnum,num[];
int N[],t[],s[],A,B,tim,ans[],pos,cas=;
bool b[maxn+],flag[maxn+];
node Q[][maxQ];
ll total; bool cmp(node n1,node n2)
{
return n1.tot<n2.tot;
} void getprim()
{
for (int i=; i<maxn; i++)
{
if (b[i]) continue;
prim[++Pnum]=i,f1[i]=Pnum;
for (int j=i+i; j<maxn; j+=i) b[j]=true;
}
for (int i=; i<; i++)
{
int k=i;
for (int j=; prim[j]<=k; j++)
while (k%prim[j]==) vet[i].push_back(prim[j]),k/=prim[j];
}
} void select_use_element()
{
int beg;
for (int i=; i<=Pnum; i++)
{
//if (prim[i]<50) continue;
//if (A%prim[i]==0) tim=1; else tim=0;
if (A%prim[i]==) beg=A;
else beg=(A-A%prim[i])+prim[i];
if (B>=beg) tim=(B-beg)/prim[i]+;
else tim=;
if (tim>) continue;
//if (prim[i]<50) continue;
for (int j=prim[i]; j<maxn; j+=prim[i]) flag[j]=true;
//if (prim[i]<=65) continue;
for (int j=prim[i]*prim[i]; j<maxn; j+=prim[i]*prim[i]) flag[j]=false;
}
tim=;
for (int i=A; i<=B; i++) if (!flag[i]) num[++tim]=i;//,cout<<i<<' ';//tim最终表示有多少个有用的数。
//cout<<" tim : "<<++cas<<' '<<tim<<" "<<A<<' '<<B<<endl;
} void output_digit(ll x)
{
while (x) cout<<(x&),x>>=; cout<<endl;
} bool check(int x,int y)
{
p=Q[x][y];
memset(ans,,sizeof ans);
for (int i=; i<=tim; i++)
if ((p.id)&((ll)<<(i-)))
{
for (unsigned k=; k<vet[num[i]].size(); k++)
ans[f1[vet[num[i]][k]]]++;
}
//for (int i=1; i<45; i++) cout<<ans[i]<<' '; cout<<endl;
for (int i=; i<; i++)
{
if (ans[i]%!=)
{
ans[]=-;
return false;
}
}
//output_digit(p.id);
ans[]=;
return true;
} void queue_operation()
{
N[]=; s[]=,t[]=;
p.id=,p.tot=;
for (int i=; i<=tim; i++)
{
cur.tot=num[i],cur.id=((ll)<<(i-));
Q[][++t[]]=cur;
}
sort(Q[]+,Q[]++t[],cmp);
int now=,next;
while (N[now]<=)
{
//cout<<"Nnow: "<<N[now]<<' '<<t[now]<<endl;
next=-now;
s[next]=,t[next]=,N[next]=N[now]+;
for (int i=s[now]; i<=t[now]; i++)
{
if (check(now,i)) return;
cur=Q[now][i];
for (pos=; ((ll)<<(pos-))<=cur.id; pos++) ;
//output_digit(cur.id);
for (int j=pos; j<=tim; j++)
if (((cur.id)&((ll)<<(j-)))==)
{
t[next]++;//=(t[next]+1)%maxQ;
p.tot=cur.tot*num[j];
p.id=(cur.id)|((ll)<<(j-));
Q[next][t[next]]=p;
}
}
sort(Q[next]+,Q[next]++t[next],cmp);
swap(now,next);
}
} void output_ans()
{
if (ans[]==-) { cout<<"none\n"; return; }
total=;
for (int i=; i<; i++)
for (int j=; j+j<=ans[i]; j++) total*=prim[i];
cout<<total<<endl;
} int main()
{
//freopen("C:/Users/Administrator/Desktop/data.in","r",stdin);
//freopen("C:/Users/Administrator/Desktop/data.out","w",stdout);
getprim();
while (cin>>A>>B)
{
memset(ans,,sizeof ans);
ans[]=-;
for (tim=; tim*tim<=B; tim++) if (tim*tim>=A) break;
if (tim*tim<=B)
{
cout<<tim<<endl;
continue;
}
memset(flag,false,sizeof flag);
select_use_element();
queue_operation();
output_ans();
}
return ;
}

H Hip To Be Square Day5——NWERC2012的更多相关文章

  1. 2012-2013 Northwestern European Regional Contest (NWERC 2012)

    B - Beer Pressure \(dp(t, p_1, p_2, p_3, p_4)\)表示总人数为\(t\),\(p_i\)对应酒吧投票人数的概率. 使用滚动数组优化掉一维空间. 总的时间复杂 ...

  2. FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  3. GNU C 扩展(转)

    GNU CC 是一个功能非常强大的跨平台 C 编译器,它对 C 语言提供了很多扩展,这些扩展对优化.目标代码布局.更安全的检查等方面提供了很强的支持.这里对支持支持 GNU 扩展的 C 语言成为 GN ...

  4. Java 中的泛型详解-Java编程思想

    Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的 ...

  5. Berserk Rook

    Berserk Rook As you may know, chess is an ancient game for which almost everyone has at least a basi ...

  6. Postman接口自动化测试实例用到的完整的SM2前端加密算法代码

    var __g__ = {}; !function(t,e){"object"==typeof exports?module.exports=exports=e():"f ...

  7. 调试器GDB的基本使用方法

    GDB调试的三种方式: 1. 目标板直接使用GDB进行调试. 2. 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端. 3. 目标板使用ulimit -c unlimited ...

  8. Python--Click

    Click Click 是 Flask 的开发团队 Pallets 的另一款开源项目,它是用于快速创建命令行的第三方模块. 我们知道,Python 内置了一个 Argparse 的标准库用于创建命令行 ...

  9. C#学习之委托和事件

    C#学习中,关于委托和事件的一些见解: 一.C语言中的函数指针 想要理解什么是委托,就要先理解函数指针的概念.所谓函数指针,就是指向函数的指针(等于没说-.-).比如我定义了两个函数square和cu ...

随机推荐

  1. 20155322 2016-2017-2 《Java程序设计》第4周学习总结

    20155322 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 本周的学习内容为课本第六章与第七章: 第六章主要讲继承和多态.首先是我们为什么要学习继承和多 ...

  2. 变态的iis10

    IIS10发布网站不能使用.NET4.0需要重新注册在之前版本的系统中使用如下命令可以直接重新注册: 但是windowsServer2016(iis 10) 使用该命令 提示 版本不支持 C:\WIN ...

  3. Yii2 模块module笔记

    包含内容: 使用GII新建module 建立子模块 在其他控制器中调用模块的操作(action) 1. 使用Gii工具新建module 注意模块的路径,我们没有写backend\modules\Art ...

  4. mysql-5.7.17-winx64免安装版环境配置 问题小记

    安装版问题请自行百度或google 这里总结几个免安装版mysql-5.7.17-winx64配置后,出现问题的解决方法. 具体的环境配置请先参考mysql-5.7.17-winx64免安装版,win ...

  5. C++操作符优先级带来的错误

    在刷LeetCode题目:190. 颠倒二进制位:颠倒给定的 32 位无符号整数的二进制位时,可以利用左移和右移操作符来实现数字翻转: 错误解法: class Solution { public: u ...

  6. 【洛谷】题解 P1056 【排座椅】

    题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...

  7. iOS 播放音频文件

    //        播放音乐 NSString *path = [[NSBundle mainBundle] pathForResource:@"1670" ofType:@&qu ...

  8. Query类型_JDBC的方法_JAVA方法_Loadrunner脚本

    数据库查询压力测试脚本 jdbc_java_查询类型接口测试 package com.test; import java.sql.Connection; import java.sql.DriverM ...

  9. Linux建立互信关系(ssh公钥登录)

    Linux有多种登录方式,比如telnet.ssh.支持ssh登录方式:口令登录和公钥登录 ssh登录方式:ssh [-l login_name] [-p port] [user@]hostname ...

  10. Ryu学习总结(持续更新)

    Ryu学习总结 该篇学习笔记,与其他分析Ryu控制器代码的笔记不同,主要按照程序的构成来进行分块总结,由于本人为新手入门,不能保证没有错误,如果发现错误,欢迎指教. 以下的内容主要来源: 源码 官方文 ...