题目链接:N - 方程的解

给定一个四元二次方程:

Ax1^2+Bx2^2+Cx3^2+Dx4^2=0

试求−1000≤x1,x2,x3,x4≤1000非零整数解的个数。

−10000≤A,B,C,D≤10000

输出解的个数。

解法:

首先这道题直接用网上HDU1496的板子过不去,原因是1e10的数组开不了那么大的。所以这里只能换思路。新思路如下(很典型的折半枚举,也就是meet-in-middle):

  1. 把X1,X2的答案存下来(存在一个2000*2000的数组里面),然后排序
  2. 二分查找这个数组里面有多个数x了
  3. AX_1^2+BX_2^2=-(CX_3^2+DX_4^2)
  4. 左边式子的答案我们已经存下来了,接下来算右边的
  5. 右边答案算出来过后,我们直接在左边数组里面二分有多少个一样的数值,答案加上这个数值就ok了

当然这里用数组会稍显笨拙,可以用map,卡时间可以过。

注意s[a*i*i + b*j*j]++会爆int,因此需要将a改为long long

代码如下:

#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
map<ll, ll>s; int main() {
ll a, b, c, d;
while (scanf("%lld %lld %lld %lld", &a, &b, &c, &d) != EOF) {
if (a * b > 0 && b * c > 0 && c * d > 0) {
printf("0\n");
return 0;
}
for (ll i = 1; i <= 1000; i++) {
for (ll j = 1; j <= 1000; j++) {
//if (i == 0 || j == 0)continue;
s[a*i*i + b*j*j]++;
}
}
ll sum = 0;
for (ll i = 1; i <= 1000; i++) {
for (ll j = 1; j <= 1000; j++) {
//if (i == 0 || j == 0)continue;
ll t = c*i*i + d*j*j;
sum += s[0 - t];
}
}
printf("%lld\n", 16*sum);
}
return 0;
}

上面说了卡常数不是很严的做法,如果卡常数很严的话,比如x的范围变到4000,map就会T掉,这里直接采用hash的方法

关键词:数字hash

例题:Uva1152:4 Values whose Sum is 0

//hash数字编码
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
map<ll, ll>s;
int a[4005], b[4005], c[4005], d[4005];
int n, T, cnt; //w[i]表示第i个结点存储的数(也就是a+b),st[i]表示第i个结点有多少种表示方法
const int hashsize = 1000003;
int hd[hashsize], nxt[16000005], w[16000005], st[16000005];
void in(int x) {
int h = (x % hashsize + hashsize) % hashsize, u = hd[h];
while (u) {
if (w[u] == x) {
st[u]++;
return;
}
u = nxt[u];
}
nxt[++cnt] = hd[h];
hd[h] = cnt;
w[cnt] = x;
st[cnt] = 1;
} int srch(int x) {
int h = (x % hashsize + hashsize) % hashsize;//查询的数是负数,所以要这么算;
int u = hd[h];
while (u) {
if (w[u] == x) return st[u];
u = nxt[u];
}
return 0;
} int main() {
scanf("%d", &T);
while (T--) {
cnt = 0; memset(hd, 0, sizeof(hd));
scanf("%d", &n);
int A, B, C, D;
for (int i = 0; i < n; i++) {
scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
}
for (ll i = 0; i < n; i++) {
for (ll j = 0; j < n; j++) {
in(a[i] + b[j]);
}
}
ll sum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++){
sum += srch(-c[i] - d[j]);
}
}
printf("%lld\n", sum);
if (T) printf("\n");
}
return 0;
}

折半枚举+Hash(HDU1496升级版)的更多相关文章

  1. poj2002 Squares(hash+折半枚举)

    Description A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-d ...

  2. poj1840 Eqs(hash+折半枚举)

    Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The co ...

  3. Load Balancing 折半枚举大法好啊

    Load Balancing 给出每个学生的学分.   将学生按学分分成四组,使得sigma (sumi-n/4)最小.         算法:   折半枚举 #include <iostrea ...

  4. CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。

    1514: Packs Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 61  Solved: 4[Submit][Status][Web Board] ...

  5. NYOJ 1091 超大01背包(折半枚举)

    这道题乍一看是普通的01背包,最最基础的,但是仔细一看数据,发现普通的根本没法做,仔细观察数组发现n比较小,利用这个特点将它划分为前半部分和后半部分这样就好了,当时在网上找题解,找不到,后来在挑战程序 ...

  6. Codeforces 888E - Maximum Subsequence(折半枚举(meet-in-the-middle))

    888E - Maximum Subsequence 思路:折半枚举. 代码: #include<bits/stdc++.h> using namespace std; #define l ...

  7. Codeforces 912 E.Prime Gift (折半枚举、二分)

    题目链接:Prime Gift 题意: 给出了n(1<=n<=16)个互不相同的质数pi(2<=pi<=100),现在要求第k大个约数全在所给质数集的数.(保证这个数不超过1e ...

  8. poj_3977 折半枚举

    题目大意 给定N(N<=35)个数字,每个数字都<= 2^15. 其中一个或多个数字加和可以得到s,求出s的绝对值的最小值,并给出当s取绝对值最小值时,需要加和的数字的个数. 题目分析 需 ...

  9. POJ 3977 Subset(折半枚举+二分)

    SubsetTime Limit: 30000MS        Memory Limit: 65536KTotal Submissions: 6754        Accepted: 1277 D ...

随机推荐

  1. win10电脑搭建网站

    新建网站之后,IIS错误提示是:在计算机“.”上没有找到服务W3SVC,需要在“启动或关闭windows功能”添加.net 3.5下面的两个程序. https://img-blog.csdn.net/ ...

  2. 跨域的两种解决方法jsonp和CORS

    1.跨域 什么是跨域? 当你请求的url是不同源的数据的时候,浏览器一般会抛出请求跨域的错误,如下图: 造成跨域的原因? 即你违反了浏览器的同源策略的限制=>阻止一个域的js脚本和另外一个域的内 ...

  3. 单页应用(SPA,Single-page-App)和多页应用(MPA,Multi-page App)的区别

    单页应用(SPA,Single-page-App)和多页应用(MPA,Multi-page App)的区别 参考博客:https://www.jianshu.com/p/4c9c29967dd6

  4. cesium结合geoserver利用WFS服务实现图层新增(附源码下载)

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...

  5. mysql必知必会--用正则表达式 进行搜索

    正则表达式介绍 前两章中的过滤例子允许用匹配.比较和通配操作符寻找数据.对 于基本的过滤(或者甚至是某些不那么基本的过滤),这样就足够了.但 随着过滤条件的复杂性的增加, WHERE 子句本身的复杂性 ...

  6. 802.11有线等效加密WEP

    有线等效加密(WEP)标准是802.11无线安全早期的解决方案,WEP并不安全. 既然WEP并不安全,为什么还要学习WEP呢? WEP简单,相比后续出现的加密协议,它不要求有多么强大的计算能力.一些老 ...

  7. 苹果Mac电脑永久路由的添加 & Mac 校园网连接教程

    学校校园网面向全校师生开放,无奈Windows用户基数大,学校只为Windows平台制作了内网连接工具,Mac平台资源较少,本人查阅相关资料后,总结整理出以下步骤,方便本校学生连接校园网.有永久路由添 ...

  8. Lucene之查询索引

    Query子类 TermQuery:根据域和关键词进行搜索 /** * termQuery根据域和关键词进行搜索 */ @Test public void termQuery() throws IOE ...

  9. centos7 字体库。vim乱码

    centos7 字体库.vim乱码 windows上传文件到centos,需要先使用dos2unix命令进行格式转换 先查看/usr/share下有没有这两个文件 没有的话yum -y install ...

  10. Linux 防SSH暴力攻击

    在下这几天发现我的VPS 总是莫名遭受到 江苏镇江那边的IP 登录请求攻击 ,跟踪了下路由,发现ip是从蒙古那边出去的,然后意识到可能是有扫描端口的.. 方法一: 现在的互联网非常不安全,很多人没事就 ...