题目链接:https://ac.nowcoder.com/acm/contest/625/B

解法:这题其实就是求2^18个点内最近的两个点的距离。我们可以容易想到朴素解法:把每个点作为源点跑最短路取最小值。也很容易想到这个做法严重超时。

对于这种构图,这里有一个比较套路的方法:枚举2进制位数k,按二进制k位的0/1分成两组跑最短路。为什么是正确的,因为一旦两个数不等,那么这两个数必定在至少一个二进制位上不同,我们枚举了所有的二进制位,那么任意两个数都会被至少一次分到不同组中,亦即所有情况的最短路都考虑到了,那么当然是正确的。

这道题能得到一个启发:像这种对于一个很大很大的图,但是其实只有很少点是我们要计算的,我们可以考虑想出一种分组方式能使得任两个数都至少一次分到不同组,这就能减少时间而且不遗漏。

细节详见代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const long long P=;
const long long INF=(long long)<<;
typedef long long LL;
const int N=2e5+;
const int M=;
typedef pair<int,int> pii;
int n,ans,a[N],cost[(<<M)+][M],d[(<<M)+],mark[(<<M)+];
bool vis[(<<M)+]; inline LL PowMod(LL a, LL b) { LL r=; while(b) { if(b&) r=r*a%P; a=a*a%P, b>>=; } return r; } void prework() {
for (int s = ; s < (<<); ++s) {
for(int i = ; i < ; ++i) {
cost[s][i] = PowMod( max(s,s^(<<i))%P, <<i ) % P + ;
}
}
} priority_queue<pii> q;
void Dijkstra(int k) {
while (!q.empty()) q.pop();
memset(d,0x3f,sizeof(d));
memset(vis,,sizeof(vis));
for (int i=;i<=n;i++)
if (a[i]>>k & ) { //把n个数字 分成2组 跑最短路
q.push(make_pair(,a[i]));
d[a[i]]=;
}
while (!q.empty()) {
pii x=q.top(); q.pop();
if (mark[x.second] && x.first!=) ans=min(ans,-x.first);
if (-x.first>=ans) return; //当前最短路都比答案大,后面的不用看
if (vis[x.second]) continue;
vis[x.second]=; for (int i=;i<;i++) {
int y=x.second^(<<i);
if (d[y]>d[x.second]+cost[x.second][i]) {
d[y]=d[x.second]+cost[x.second][i];
q.push(make_pair(-d[y],y));
}
}
}
} signed main()
{
prework(); scanf("%lld",&n);
for (int i=;i<=n;i++) scanf("%lld",&a[i]),mark[a[i]]=;
sort(a+,a+n+);
for (int i=;i<=n;i++)
if (a[i]==a[i-]) { puts(""); return ; } ans=INF;
for (int i=;i<;i++) Dijkstra(i);
cout<<ans<<endl;
return ;
}

2019华工校赛 B - 修仙时在做什么?有没有空?可以来炼丹吗?的更多相关文章

  1. 2019年华南理工大学程序设计竞赛(春季赛) B 修仙时在做什么?有没有空?可以来炼丹吗?(思维建图搜索)

    https://ac.nowcoder.com/acm/contest/625/B 分析: 全部的状态只有1<<18 个 , 所以我们可以预处理 f[u][j] , 然后建立出全部的u可以 ...

  2. [Ynoi2018]末日时在做什么?有没有空?可以来拯救吗?

    这道题真的超级...毒瘤 + 卡常 + 耗 RP 啊... 传送门 noteskey 题解看 shadowice 大仙 的 code 如果发现自己 T 掉了,别心急,洗把脸再交一遍试试... //by ...

  3. oo修仙之路

    写在前面: 之前听说过oo这门课的威力,计院全体修仙现场的图也被转了不知多少遍,然而自己不亲身经历就不知这门课的难度所在.每次debug时耳边总会想起三国杀里面周瑜的话"挣扎吧,在血和暗的深 ...

  4. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截

    程序猿修仙之路--数据结构之你是否真的懂数组?   数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少. ...

  5. ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

    ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...

  6. ICPC 2019 徐州网络赛

    ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...

  7. 《带你装B,带你飞》pytest修仙之路3 - setup/teardown

    1. 简介 学过unittest的都知道里面用前置和后置setup和teardown非常好用,在每次用例开始前和结束后都去执行一次.当然还有更高级一点的setupClass和teardownClass ...

  8. 《带你装B,带你飞》pytest修仙之路5 - yield操作

    1. 简介 上一篇中,我们刚刚实现了在每个用例之前执行初始化操作,那么用例执行完之后如需要清除数据(或还原)操作,可以使用 yield 来实现.fixture通过scope参数控制setup级别,既然 ...

  9. ACM-ICPC 2019 山东省省赛总结

    五题手快拿银,不然拿铜,甚至不拿,从结果上来看拿了铜牌对第一年的我们来说算好的,也不算太好. 从拿奖后的第一天,我想写这篇博客,但是我忍了下来,那时候被喜悦冲昏了头脑,当 冷静下来,我开始打算写这篇博 ...

随机推荐

  1. Dev常用控件

    GridControl TreeView DEV GridControl小结.. https://blog.csdn.net/happy09li/article/details/7186829 Dev ...

  2. SpringMvc获取前端的数据@RequestBody请求体/@PathVaribale/@RequestParam【支持Ajax】

    一.@RequestBody请求体 注意请求体只有form表单才有,而对于链接来说不使用 1).在Controller中写 @RequestBody String body是基本用法 另外可以封装对象 ...

  3. Spring data jpa persistence .xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://j ...

  4. 深入理解volatile关键字

    Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作内存 ...

  5. Steup Factory 操作注册表

    //判断注册表是否存在,不存在就创建 result = Registry.DoesKeyExist(HKEY_CURRENT_USER, "SOFTWARE\\MyTestApp" ...

  6. cerebro使用

    一.安装cerebro 上传插件到任意路径 tar zxvf 解压插件包 [root@ngsocdev14 es]# ls cerebro-0.8.3.zip software [root@ngsoc ...

  7. boost库:字符串处理

    使用boost库的字符串处理之前,需要进行区域设置.类:std::locale,每个C++程序自动拥有一个此类的实例,不能直接访问全局区域设置. 全局区域设置可以使用类std::locale中的静态函 ...

  8. shell脚本学习(2)查找

    1 grep 用法: grep -F  fa      找含有fa字符的字符串 yuyuyu@ubuntu:~$ grep -F fa < do.txt grep -i  fa      忽略大 ...

  9. PHP chgrp() 函数

    定义和用法 chgrp() 函数改变指定文件的用户组. 如果成功则返回 TRUE,如果失败则返回 FALSE. 语法 chgrp(file,group) 参数 描述 file 必需.规定要检查的文件. ...

  10. UNP学习第六章select

    一.I/O复用典型的网络应用场合 当客户处理多个描述字时,必须使用I/O复用,这在前一段中已做了描述. 一个客户同时处理多个套接口时可能的,但很少出现. 如果一个TCP服务器既要处理监听套接口,又要处 ...