https://ac.nowcoder.com/acm/contest/920#question

A

构造+双指针
发现m的限制是1e5,而点数是5e4,所以不能构造太多的边,思考一下最短路树的定义。会发现其实就是要构造出一个最短路树。按\(a_i\)升序排序,那么只需要找一个在\(a_i-S\)的点连边即可。这个玩意可以直接用双指针或者二分或者其他什么数据结构来实现。判断无解即判断是否存在大于S的边或者0边。复杂度\(O(n \log n)\)

#include <bits/stdc++.h>
using namespace std;namespace io {
char buf[1<<21], *p1 = buf, *p2 = buf;
inline char gc() {if(p1 != p2) return *p1++;p1 = buf;p2 = p1 + fread(buf, 1, 1 << 21, stdin);return p1 == p2 ? EOF : *p1++;
}
#define G gc#ifndef ONLINE_JUDGE
#undef G
#define G getchar
#endiftemplate<class I>
inline void read(I &x) {x = 0; I f = 1; char c = G();while(c < '0' || c > '9') {if(c == '-') f = -1; c = G(); }while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = G(); }x *= f;
}
template<class I>
inline void write(I x) {if(x == 0) {putchar('0'); return;}I tmp = x > 0 ? x : -x;if(x < 0) putchar('-');int cnt = 0;while(tmp > 0) {buf[cnt++] = tmp % 10 + '0';tmp /= 10;}while(cnt > 0) putchar(buf[--cnt]);
}#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')} using namespace io;#define ll long long
const int N = 100010;int n, S, m;
struct Node {int v, id;} a[N];
struct edge {int u, v, w;} e[N];bool operator < (Node a, Node b) {return a.v < b.v;
}int main() {read(n); read(S);for(int i = 1; i <= n; ++i) read(a[i].v), a[i].id = i;sort(a + 1, a + n + 1);bool flag = 0; int last = 1;for(int i = 2; i <= n; ++i) {if(a[i].v == 0) {flag = 1;  break;}while(last < i && a[i].v - a[last].v > S) ++last;e[++m] = {a[last].id, a[i].id, a[i].v - a[last].v};}for(int i = 1; i <= m; ++i) if(e[i].w > S || e[i].w < 1) flag = 1;if(flag) puts("-1");else {printf("%d\n", m);for(int i = 1; i <= m; ++i) printf("%d %d %d\n", e[i].u, e[i].v, e[i].w);}return 0;
} 

B

构造+贪心+01trie
因为是一个完全图,所以题目等价于,1到n的排列中,相邻两个数作为下标,\(a_i\)的\(xor\)最大值最小是多少。
因为高位对答案的影响更大,按位考虑,我们肯定需要让当前位为1的排在一块,为0的排在一块,那么答案的最大值一定在中间接壤点(因为这两部分内部再怎么xor也没这一位的一个1贡献大)。
所以找出有0也有1的最高位,然后将序列划分为两段。那么问题就变成了,在序列0和序列1中各选出一个数,使他们的xor和尽可能小。这个01Trie维护一下就好了。
赛时是写了一个同样思想的归并排序,但是没有想到“这两部分内部再怎么xor也没这一位的一个1贡献大”这一性质,所以写挂了...

#include <bits/stdc++.h>
using namespace std;namespace io {
char buf[1<<21], *p1 = buf, *p2 = buf;
inline char gc() {if(p1 != p2) return *p1++;p1 = buf;p2 = p1 + fread(buf, 1, 1 << 21, stdin);return p1 == p2 ? EOF : *p1++;
}
#define G gc#ifndef ONLINE_JUDGE
#undef G
#define G getchar
#endiftemplate<class I>
inline void read(I &x) {x = 0; I f = 1; char c = G();while(c < '0' || c > '9') {if(c == '-') f = -1; c = G(); }while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = G(); }x *= f;
}
template<class I>
inline void write(I x) {if(x == 0) {putchar('0'); return;}I tmp = x > 0 ? x : -x;if(x < 0) putchar('-');int cnt = 0;while(tmp > 0) {buf[cnt++] = tmp % 10 + '0';tmp /= 10;}while(cnt > 0) putchar(buf[--cnt]);
}#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')} using namespace io;#define ll long long
const int N = 1000100;int n, t[N * 10][2], tot;
ll a[N], b[N][2];void insert(ll x) {int u = 0;for(ll pos = 60; pos >= 0; --pos) {int c = (x >> pos) & 1LL;if(!t[u][c]) t[u][c] = ++tot;u = t[u][c];}
}ll query(ll x) {int u = 0; ll ans = 0;for(ll pos = 60; pos >= 0; --pos) {int c = (x >> pos) & 1LL;if(t[u][c]) u = t[u][c];else u = t[u][c ^ 1], ans += 1LL << pos; }return ans;
}int main() {read(n);for(int i = 1; i <= n; ++i) read(a[i]);int cnt[2];for(ll pos = 60; pos >= 0; --pos) {cnt[0] = cnt[1] = 0;for(int i = 1; i <= n; ++i) {int c = (a[i] >> pos) & 1; b[++cnt[c]][c] = a[i];}if(cnt[0] && cnt[1]) break;}if(!cnt[0] || !cnt[1]) return puts("0"), 0;for(int i = 1; i <= cnt[0]; ++i) insert(b[i][0]);ll ans = 1LL << 61;for(int i = 1; i <= cnt[1]; ++i) ans = min(ans, query(b[i][1]));outn(ans);
}

C

最短路树+spfa
同起点到两个点的最短路的公共部分等价于该起点的最短路树上这两个点的lca到根的距离。字典序最小的话建最短路树的时候处理一下就好。将询问离线下来,每次处理出当前起点下的最短路树,然后对每个询问依次取max。这样就只用开一个最短路树的空间了。复杂度是O(nqlogn + nmk)(k为spfa中的那个常数)。正解是在建最短路树那里用Johnson算法,卡了spfa。因为过于码农所以没补这题= =记录了一下思想。
然后johnson算法的话,就是定义一个虚点,然后到每个点连长度为0的边,然后spfa一次跑出最短路,然后这个最短路就是每个节点的势能函数,记为h。那么将边权改为h[v]-h[u]+w,就能保证不存在负边权了,于是跑DIjkstra,最后将势能函数反推回去就可以得到最短路了。
这个玩意好像在rqy的Dijkstra跑费用流的课件里面看到过。

转载于:https://www.cnblogs.com/henry-1202/p/11380542.html

牛客NOIP暑期七天营-提高组1 解题报告相关推荐

  1. 牛客NOIP暑期七天营-提高组1

    牛客NOIP暑期七天营-提高组1 链接 A 边权可为0就排序建一条链子. 但是边权不为0 除了第一个有0的不行. x连向上一个比他小的数. 期间判断有无解. #include <bits/std ...

  2. 牛客NOIP暑期七天营-普及组4 C-火龙果田

    小巫女从小就喜欢吃火龙果,她有一个梦想,就是用魔法变出许许多多美味可口的火龙果,这样她就可以天天享受火龙果的美味啦! 可是小巫女平常没有认真完成魔法学院的功课,魔法经常出现一些意想不到的情形,不能变出 ...

  3. NOIP2013 提高组复赛解题报告

    NOIP2013 提高组复赛 day1 day\;1 1002. 火柴排队 贪心+数据结构/归并排序 这个"相邻交换"让我联想到了NOIP2012_day1_task2_game那 ...

  4. NOIP2018提高组Day1 解题报告

    前言 关于\(NOIP2018\),详见此博客:NOIP2018学军中学游记(11.09~11.11). 这次\(NOIP\ Day1\)的题目听说很简单(毕竟是三道原题),然而我\(T3\)依然悲剧 ...

  5. NOIP2016提高组复赛解题报告

    Day1 T1-玩具谜题 Day1 T2-天天爱跑步 Day1 T3-换教室 Day2 T1-组合数问题 Day2 T2-蚯蚓 Day2 T3-愤怒的小鸟 转载于:https://www.cnblog ...

  6. 2021牛客OI赛前集训营-提高组(第四场) T2空间跳跃

    2021牛客OI赛前集训营-提高组(第四场) 题目大意 给你三个整数 n , d , l n,d,l n,d,l, n n n为正整数.负整数或0, d , l d,l d,l为正整数,你现在有一个数 ...

  7. 2021牛客寒假算法基础集训营1 J 一群小青蛙呱蹦呱蹦呱

    今天的比赛没打( 睡午觉去了,今天太累了 晚上来看看题 2021牛客寒假算法基础集训营1 J 一群小青蛙呱蹦呱蹦呱 题目传送门 板子题( 我们知道由唯一分解定理得,若 n=p1α1×p2α2×p3α3 ...

  8. 牛客网暑期ACM多校训练营(第十场)F.Rikka with Line Graph

    牛客网暑期ACM多校训练营(第十场)F.Rikka with Line Graph 做法:\(G'\) 中的对应原图两条边(a,b) (c,d)的最短路为: \[ w[a][b] + w[c][d] ...

  9. 牛客网暑期ACM多校训练营(第九场)

    牛客网暑期ACM多校训练营(第九场) A. Circulant Matrix 做法:看到下标 \(xor\) 这种情况就想 \(FWT\),可是半天没思路,于是放弃了..其实这个 \(n\) 疯狂暗示 ...

  10. 牛客网暑期ACM多校训练营(第五场)

    牛客网暑期ACM多校训练营(第五场) A. gpa 二分答案,然后就转化为是否满足 \(\frac {\sum s[i]c[i]}{\sum s[i]} ≥ D\), \(\sum s[i]c[i] ...

最新文章

  1. 人脸识别引擎SeetaFaceEngine中Identification模块使用的测试代码
  2. JVM堆 栈 方法区详解
  3. service能去调另外一个service吗_kubernetes的service和pod是如何关联的?
  4. vue-cli3.0使用及配置(部分)
  5. LeetCode - Easy - 28. Implement strStr()
  6. 判定两个tensor维度相同_Pytorch之Tensor大详解
  7. 树莓派 4 与英伟达 Jetson Nano 性能大比拼,谁是最佳的嵌入式“电脑”?
  8. 利用 Zabbix 监控 mysqldump 定时备份数据库是否成功 | 运维进阶
  9. 小兔子(PAT乙级练习题)
  10. Python新闻网站项目-1.项目分析与产品设计
  11. Python制作2048小游戏
  12. RS485协议详解RS485与RS232优缺点比较
  13. 读书方法(三遍读书法)
  14. win10鼎信诺为什么安装不了_两个方法教你彻底解决win10系统更新补丁安装失败的问题-系统操作与应用 -亦是美网络...
  15. 微信windows版_微信Windows版更新3.0:小程序可添加至桌面
  16. HTML四季变换图,四季星空图
  17. 创始人之间应该如何量化分配股权?
  18. 教程 | Rhino Compute Sevice介绍及环境搭建
  19. #java读书笔记#基础知识
  20. node版本管理工具gnvm

热门文章

  1. java linux怎么抓tcp包_Linux使用tcpdump抓取网络数据包示例
  2. python中创建类的作用_Python中类的创建与使用详解
  3. 拓端tecdat|R语言:逻辑回归ROC曲线对角线分析过程及结果
  4. Linux下卸载miniconda3(Anaconda类系)
  5. Linux中文件目录写法
  6. Fiddler抓包工具 学习笔记
  7. Android入门笔记12
  8. pytorch自动求导数机制
  9. 史上最全的人工智能知识图谱
  10. 基于face_recognition构建的人脸识别系统以及相关应用