凡喵识图 / Image Recognition(鸽笼原理)(模拟)

凡喵识图 / Image Recognition

题目大意

给你一些 2^64 大小的数,然后每插入一个数之前,询问原本有多少个数的二进制跟它的二进制恰好有三位不同。

思路

首先不难想出 O(643n)50 分 Trie 树做法。
然后你就似乎没有头绪了。

然后你会看到数据具有随机性。
然后你就想到数很均摊。
那你考虑用一些方法暴力搞,优化的暴力搞。

然后我们考虑用鸽笼原理来优化。
什么意思呢,我们把数分成四个部分,每个 16 位二进制。
那你要恰好只有 3 位不同,那就一定要有一块是一模一样的。

那你就有思路了,你放进去的时候找前面有多少个数的这个块跟它一样。(我这里用邻接表把所有这样的数接在一起)
然后你就只跟这些数匹配,由于数据有均摊性,所以相同的会很少。
(匹配暴力匹配就可以了)
然后找出来之后把自己放进去。

然后你匹配的时候要记得去重。

然后就过了,没错,就是这么神奇,就是这么暴力。

代码

#include<cstdio> #include<algorithm> #define ll unsigned long long using namespace std; struct node { ll x; int to, nxt; }e[600001]; int n, ans, le[5][70001], a[150001], KK; ll X[150001]; void insert1(ll x, int y) { e[++KK] = (node){x, y, le[1][x]}; le[1][x] = KK; } void insert2(ll x, int y) { e[++KK] = (node){x, y, le[2][x]}; le[2][x] = KK; } void insert3(ll x, int y) { e[++KK] = (node){x, y, le[3][x]}; le[3][x] = KK; } void insert4(ll x, int y) { e[++KK] = (node){x, y, le[4][x]}; le[4][x] = KK; } bool work(int x, int y) {//匹配 int num = 0; for (int i = 0; i < 64; i++) if (((X[x] >> i) & 1) ^ ((X[y] >> i) & 1)) num++; return num == 3; } int main() { freopen("hashing.in", "r", stdin); freopen("hashing.out", "w", stdout); scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%llud", &X[i]); ans = 0; a[0] = 0; //分成四块都处理 int xx = X[i] % (1ll << 16); for (int j = le[1][xx]; j; j = e[j].nxt) a[++a[0]] = e[j].to; insert1(xx, i); xx = (X[i] >> 16) % (1ll << 16); for (int j = le[2][xx]; j; j = e[j].nxt) a[++a[0]] = e[j].to; insert2(xx, i); xx = (X[i] >> 32) % (1ll << 16); for (int j = le[3][xx]; j; j = e[j].nxt) a[++a[0]] = e[j].to; insert3(xx, i); xx = X[i] >> 48; for (int j = le[4][xx]; j; j = e[j].nxt) a[++a[0]] = e[j].to; insert4(xx, i); sort(a + 1, a + a[0] + 1); a[0] = unique(a + 1, a + a[0] + 1) - a - 1;//去重(不过你完全可以用一个桶来记录) for (int j = 1; j <= a[0]; j++)//一一判断 if (work(a[j], i)) ans++; printf("%d\n", ans); } fclose(stdin); fclose(stdout); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/jzoj_5101.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(81)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示