H Hip To Be Square Day5——NWERC2012
这个题目巨坑啊。调试的时间加起来绝对超过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的更多相关文章
- 2012-2013 Northwestern European Regional Contest (NWERC 2012)
B - Beer Pressure \(dp(t, p_1, p_2, p_3, p_4)\)表示总人数为\(t\),\(p_i\)对应酒吧投票人数的概率. 使用滚动数组优化掉一维空间. 总的时间复杂 ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- GNU C 扩展(转)
GNU CC 是一个功能非常强大的跨平台 C 编译器,它对 C 语言提供了很多扩展,这些扩展对优化.目标代码布局.更安全的检查等方面提供了很强的支持.这里对支持支持 GNU 扩展的 C 语言成为 GN ...
- Java 中的泛型详解-Java编程思想
Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的 ...
- Berserk Rook
Berserk Rook As you may know, chess is an ancient game for which almost everyone has at least a basi ...
- Postman接口自动化测试实例用到的完整的SM2前端加密算法代码
var __g__ = {}; !function(t,e){"object"==typeof exports?module.exports=exports=e():"f ...
- 调试器GDB的基本使用方法
GDB调试的三种方式: 1. 目标板直接使用GDB进行调试. 2. 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端. 3. 目标板使用ulimit -c unlimited ...
- Python--Click
Click Click 是 Flask 的开发团队 Pallets 的另一款开源项目,它是用于快速创建命令行的第三方模块. 我们知道,Python 内置了一个 Argparse 的标准库用于创建命令行 ...
- C#学习之委托和事件
C#学习中,关于委托和事件的一些见解: 一.C语言中的函数指针 想要理解什么是委托,就要先理解函数指针的概念.所谓函数指针,就是指向函数的指针(等于没说-.-).比如我定义了两个函数square和cu ...
随机推荐
- 20155235 《Java程序设计》 实验二 实验三 敏捷开发与XP实践
20155235 <Java程序设计> 实验二 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验内容 没有Linux基础的同学建议先学习<Linux基础入 ...
- 20155302 2016-2017-2 《Java程序设计》第十周学习总结
20155302 2016-2017-2 <Java程序设计>第十周学习总结 教材学习内容总结 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 网络最主要的优势在于共享 ...
- day9 匿名函数 lambda
1. list列表排序 #### sort排序 nums = [,,,,,] nums.sort() print(nums) ### 结果 [, , , , , ] ######## 逆序 In [] ...
- CF543E Listening to Music
题面 空间只有$64\text{MB}$!!! 题解 (据说正解是毒瘤分块套分块) 按照权值从大到小排序,对所有能够覆盖到它的区间的左端点打个标记 按照值域建一棵主席树就可以了 区间查询最大值,用$m ...
- SIM_AT_Command
下面是GET请求 AT+HTTPPARA? 查询设置的Para命令 AT+SAPBR=1,1 (模块启动后设置一次即可)OK AT+HTTPINIT (初始化)OK AT+HTTPPARA=CONTE ...
- 跨越适配&性能那道坎,企鹅电竞Android weex优化
WeTest 导读 企鹅电竞从17年6月接入weex,到现在已经有一年半的时间,这段时间里面,针对遇到的问题,企鹅电竞终端主要做了下面的优化: image组件 预加载 预渲染 Image组件 weex ...
- SQL基本数据类型等
bit 类似C#中的bool类型 true/false int 整型 nvarchar 字符串类型 float 小数型 decimal(,) 小数型 (限制小数位数) dateti ...
- C# 合并多个结构相同的DataTable
public DataTable GetAllDataTable(DataSet ds) { DataTable newDataTable = ds.Tables[0].Clone(); //创建新表 ...
- hdu1042 N!(大数求阶乘)
N! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submi ...
- POJ 3278 Catch That Cow (附有Runtime Error和Wrong Answer的常见原因)
题目链接:http://poj.org/problem?id=3278 Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total S ...