HDU6046 hash 【2017多校联训第二场B】
2017-07-27 22:16
309 查看
传送门
题目大意:给出一个106∗106的矩阵的每一位的计算方式,然后给出一个103∗103的矩阵,求这个矩阵出现的位置。
题解:对于小矩阵的每一个位置求出这个位置以及之后63位的值压在一个unsigned long long里面。因为这个大矩阵是完全随机的,而且264远大于1012所以我们可以认为,只要压的那个64位的unsigned long long相同,就是同一个位置。所以我们现在已经有了一个手段,猜任意一个位置,我们能判断是不是在小矩阵中。所以我们就可以开始枚举位置。但是显然我们一个一个地枚举位置是不可取的,所以枚举是需要技巧的,我们可以以1000为基数跳着寻找下一个位置,然后总的时间复杂度就是O((106103)2⋅64)
看不懂就看看代码吧,表达能力捉鸡……
题目大意:给出一个106∗106的矩阵的每一位的计算方式,然后给出一个103∗103的矩阵,求这个矩阵出现的位置。
题解:对于小矩阵的每一个位置求出这个位置以及之后63位的值压在一个unsigned long long里面。因为这个大矩阵是完全随机的,而且264远大于1012所以我们可以认为,只要压的那个64位的unsigned long long相同,就是同一个位置。所以我们现在已经有了一个手段,猜任意一个位置,我们能判断是不是在小矩阵中。所以我们就可以开始枚举位置。但是显然我们一个一个地枚举位置是不可取的,所以枚举是需要技巧的,我们可以以1000为基数跳着寻找下一个位置,然后总的时间复杂度就是O((106103)2⋅64)
看不懂就看看代码吧,表达能力捉鸡……
#include <bits/stdc++.h> const int MAXN = 1e3 + 5, MXM = 1e6; const int L = 1e3, ZIP = 64; #define LL unsigned long long using namespace std; inline unsigned sfr(unsigned h, unsigned x) { return h >> x; } inline unsigned Ran() { return rand() << 15 | rand(); } int f(LL i, LL j) { LL w = i * 1000000ll + j; int h = 0; for(int k = 0; k < 5; ++k) { h += (int) ((w >> (8 * k)) & 255); h += (h << 10); h ^= sfr(h, 6); } h += h << 3; h ^= sfr(h, 11); h += h << 15; return sfr(h, 27) & 1; } const int MOD = 1313131; struct HashMap { int adj[MOD], cc, nxt[MAXN * MAXN]; LL val[MAXN * MAXN], pos[MAXN * MAXN]; void clr() { memset(adj, 0, sizeof adj); cc = 0; } inline void Ins(LL v, LL p) { int t = v % MOD; ++ cc; val[cc] = v; pos[cc] = p; nxt[cc] = adj[t]; adj[t] = cc; } inline LL Find(LL v) { int u = v % MOD; for(int i = adj[u]; i; i = nxt[i]) if(val[i] == v) return pos[i]; return 0; } } mp; char s[MAXN]; LL hsh[MAXN]; int main () { int T; scanf("%d", &T); for(int Cas = 1; Cas <= T; ++ Cas) { for(int i = 1; i<=L; i++) { scanf("%s", s+1); for(int j = 1; j <= L; j++) { hsh[j] = (hsh[j-1]<<1)+(s[j]=='1'); } for(int j = 1; j<=(L-ZIP+1); j++) mp.Ins(hsh[j+ZIP-1], 1000001LL*i+j); } LL ans = 0; int px, py; for(int i = 1; (!ans) && i <= MXM; i += 1000) for(int j = 1; (!ans) && j <= MXM; j += 900) { if(j+ZIP-1 > MXM) continue ; LL hsh = 0; for(int t = 0; t<ZIP; t++) hsh = (hsh<<1) + f(i, j+t); if((ans=mp.Find(hsh)) != 0) { px = i, py = j; break; } } int x = ans / 1000001ull, y = ans % 1000001ull; printf("Case #%d :%d %d\n", Cas, px-x+1, py-y+1); if(Cas != T) mp.clr(); } }
相关文章推荐
- 2017 计蒜之道 第二场 A. 百度的年会游戏
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017湖南多校第二场-20170312
- Russian Code Cup 2017 - Finals B. Similar Words(hash+树形dp)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 多校训练第二场 HDU 6055 Regular polygon
- hdu 6047: Maximum Sequence (2017 多校第二场 1003)【贪心】
- (2017多校训练第二场)HDU - 6053 TrickGCD 初见莫比乌斯
- HDU6046-hash
- 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(一起消消毒)
- 2017 计蒜之道 初赛 第二场 A题(百度的年会游戏)
- 2017西安邀请赛: I. Barty's Computer(暴力+Hash)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 腾讯2017秋招笔试编程题:geohash [python]
- 2017 杭电多校联赛第二场 1003 Maximum Sequence(单调队列)HDU 6047
- 2017 7.27多校训练第二场补题
- 2017 Multi-University Training Contest - 第二场 09 TrickGCD (容斥+莫比乌斯)
- 2017 多校训练第二场 HDU 6053 TrickGCD
- 2017 多校训练第二场 HDU 6052 To my boyfriend
- 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(神奇的数)