2018冬令营模拟测试赛(十九)

[Problem A]小Y

试题描述

输入

见“试题描述

输出

见“试题描述

输入示例

见“试题描述

输出示例

见“试题描述

数据规模及约定

见“试题描述

题解

目前未知。

这题目前就能做到 \(O(n \sqrt{M} \log n)\),其中 \(M\) 是逆序对数,然而会被卡 T;当然这题暴力可以拿到和左边那个算法一样的分数,只要暴力加一个剪枝:当左区间最大值小于右区间最小值时就直接输出阶乘。

// 略(不要打我 TAT)

[Problem B]暗牧

试题描述

输入

见“试题描述

输出

见“试题描述

输入示例

见“试题描述

输出示例

见“试题描述

数据规模及约定

见“试题描述

题解

这题要用到的节点不多,自然想到构建虚树。把所有边和询问所提到的点都作为关键点,每棵树分别处理,这样能把点数压成 \(4(m+q)\),边数也是这个级别的,最后跑 \(q\) 遍最短路就好了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <vector>
#include <queue>
#include <cassert>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)int read() {int x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f;
}#define maxtrn 300010
#define maxlog 19
#define maxom 100010
#define maxn 400050
#define maxm 1000090
#define ool (1ll << 60)
#define LL long long
#define pii pair <int, int>
#define x first
#define y second
#define mp(x, y) make_pair(x, y)int ToT;
struct Graph {int m, head[maxn], nxt[maxm], to[maxm], dist[maxm];void AddEdge(int a, int b) {to[++m] = b; nxt[m] = head[a]; head[a] = m;swap(a, b);to[++m] = b; nxt[m] = head[a]; head[a] = m;return ;}void AddEdge(int a, int b, int c) {assert(a >= 0 && b >= 0);// printf("edge %d %d, %d\n", a, b, c);to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;swap(a, b);to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;return ;}
} tr, G;int fa[maxtrn][maxlog], dep[maxtrn], dfn[maxtrn], clo;
void build(int u) {dfn[u] = ++clo;rep(i, 1, maxlog - 1) fa[u][i] = fa[fa[u][i-1]][i-1];for(int e = tr.head[u]; e; e = tr.nxt[e]) if(tr.to[e] != fa[u][0]) {fa[tr.to[e]][0] = u;dep[tr.to[e]] = dep[u] + 1;build(tr.to[e]);}return ;
}
int lca(int a, int b) {if(dep[a] < dep[b]) swap(a, b);dwn(i, maxlog - 1, 0) if(dep[a] - dep[b] >= (1 << i)) a = fa[a][i];dwn(i, maxlog - 1, 0) if(fa[a][i] != fa[b][i]) a = fa[a][i], b = fa[b][i];return a == b ? a : fa[b][0];
}struct Edge {int p1, u1, p2, u2;Edge() {}Edge(int _1, int _2, int _3, int _4): p1(_1), u1(_2), p2(_3), u2(_4) {}
} es[maxom], qs[15];
int num[(maxom<<1)+20], cntn, gnode[maxtrn<<1];
vector <int> vnode[(maxom<<1)+20];
const bool cmp(const int& a, const int& b) {return dfn[a] < dfn[b];
}
const bool cmpequ(const int& a, const int& b) {return dfn[a] == dfn[b];
}const int HMOD = 1000037;
struct Hash {int tot, head[HMOD], nxt[maxn], id[maxn];pii key[maxn];void Insert(pii a, int v) {// printf("insert: pair(%d, %d) %d\n", a.x, a.y, v);int u = (a.x * 233 + a.y) % HMOD;nxt[++tot] = head[u]; id[tot] = v; key[tot] = a; head[u] = tot;return ;}int Find(pii a) {int u = (a.x * 233 + a.y) % HMOD;for(int e = head[u]; e; e = nxt[e]) if(key[e].x == a.x && key[e].y == a.y) return id[e];return -1;}
} hh;struct Node {int u; LL d;Node() {}Node(int _, LL __): u(_), d(__) {}bool operator < (const Node& t) const { return d > t.d; }
};
LL d[maxn];
bool vis[maxn];
priority_queue <Node> Q;
LL ShortPath(int s, int t) {rep(i, 1, ToT) d[i] = ool;memset(vis, 0, sizeof(vis));d[s] = 0;Q.push(Node(s, 0));while(!Q.empty()) {int u = Q.top().u; Q.pop();if(vis[u]) continue;vis[u] = 1;for(int e = G.head[u]; e; e = G.nxt[e]) if(d[G.to[e]] > d[u] + G.dist[e]) {d[G.to[e]] = d[u] + G.dist[e];if(!vis[G.to[e]]) Q.push(Node(G.to[e], d[G.to[e]]));}}return d[t];
}int main() {int n = read(), m = read(), q = read();rep(i, 1, n - 1) {int a = read(), b = read();tr.AddEdge(a, b);}build(1);rep(i, 1, m) {int p1 = read(), u1 = read(), p2 = read(), u2 = read();es[i] = Edge(p1, u1, p2, u2);num[++cntn] = u1; num[++cntn] = u2;}rep(i, 1, q) {int p1 = read(), u1 = read(), p2 = read(), u2 = read();qs[i] = Edge(p1, u1, p2, u2);num[++cntn] = u1; num[++cntn] = u2;}sort(num + 1, num + cntn + 1);cntn = unique(num + 1, num + cntn + 1) - num - 1;rep(i, 1, m) {es[i].u1 = lower_bound(num + 1, num + cntn + 1, es[i].u1) - num;es[i].u2 = lower_bound(num + 1, num + cntn + 1, es[i].u2) - num;// printf("%d <- %d; %d <- %d\n", es[i].u1, es[i].p1, es[i].u2, es[i].p2);vnode[es[i].u1].push_back(es[i].p1);vnode[es[i].u2].push_back(es[i].p2);}rep(i, 1, q) {qs[i].u1 = lower_bound(num + 1, num + cntn + 1, qs[i].u1) - num;qs[i].u2 = lower_bound(num + 1, num + cntn + 1, qs[i].u2) - num;// printf("%d <- %d; %d <- %d\n", qs[i].u1, qs[i].p1, qs[i].u2, qs[i].p2);vnode[qs[i].u1].push_back(qs[i].p1);vnode[qs[i].u2].push_back(qs[i].p2);}rep(i, 1, cntn) {sort(vnode[i].begin(), vnode[i].end(), cmp);vector <int> :: iterator it = unique(vnode[i].begin(), vnode[i].end(), cmpequ);vnode[i].erase(it, vnode[i].end());// printf("tree %d:", i); for(auto j : vnode[i]) printf(" %d", j); putchar('\n');int cntg = 0;rep(j, 0, vnode[i].size() - 1) {gnode[++cntg] = vnode[i][j];if(j < vnode[i].size() - 1) gnode[++cntg] = lca(vnode[i][j], vnode[i][j+1]);}sort(gnode + 1, gnode + cntg + 1, cmp);cntg = unique(gnode + 1, gnode + cntg + 1, cmpequ) - gnode - 1;rep(j, 1, cntg) hh.Insert(mp(i, gnode[j]), ++ToT);rep(j, 1, cntg)if(j > 1) {int a = lca(gnode[j-1], gnode[j]);G.AddEdge(hh.Find(mp(i, a)), hh.Find(mp(i, gnode[j])), dep[gnode[j]] - dep[a]);}}rep(i, 1, m) G.AddEdge(hh.Find(mp(es[i].u1, es[i].p1)), hh.Find(mp(es[i].u2, es[i].p2)), 1);rep(i, 1, q) {int p1 = qs[i].p1, u1 = qs[i].u1, p2 = qs[i].p2, u2 = qs[i].u2;LL ans = ShortPath(hh.Find(mp(u1, p1)), hh.Find(mp(u2, p2)));if(ans < ool) printf("%lld\n", ans); else puts("impossible");}return 0;
}

[Problem C]大根

试题描述

输入

见“试题描述

输出

见“试题描述

输入示例

见“试题描述

输出示例

见“试题描述

数据规模及约定

见“试题描述

题解

这题可以转化成生成 \(k\) 个不相交区间,要求每个元区间都包含至少一个生成的区间,且生成的区间至少被一个原区间包含。

于是变成两种贪心取最优:

  • 将包含别的区间的区间放到集合 \(B\) 中,否则放到集合 \(A\) 中,然后枚举 \(A\) 中分 \(k_1\) 类,那么 \(B\) 中选择 \(k - k_1\) 个。\(B\) 中选的一定是单个区间。这样能保证合法(想想为什么)。

  • 按长度排序取前 \(k-1\) 个,然后剩下的所有分一类。(这就是在上面有区间集合的交集为 \(0\) 的时候这种贪心才会起作用)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)int read() {int x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f;
}#define maxn 1000010
#define LL long longstruct Line {int l, r;Line() {}Line(int _, int __): l(_), r(__) {}bool operator == (const Line& t) const { return l == t.l && r == t.r; }bool operator < (const Line& t) const { return r != t.r ? r < t.r : l > t.l; }Line operator * (const Line& t) const { return Line(max(l, t.l), min(r, t.r)); }Line operator *= (const Line& t) { *this = *this * t; return *this; }
} ls[maxn], getl[maxn], bigl[maxn];
int n, K, cntg, cntb, val[maxn];bool cmplen(Line a, Line b) { return a.r - a.l > b.r - b.l; }int main() {n = read(); K = read();rep(i, 1, n) {int l = read(), r = read();ls[i] = Line(l, r);}sort(ls + 1, ls + n + 1);for(int i = 1; i <= n; ) {getl[++cntg] = ls[i++];while(i <= n && ls[i] * ls[i-1] == ls[i-1]) bigl[++cntb] = ls[i++];}sort(bigl + 1, bigl + cntb + 1, cmplen);sort(getl + 1, getl + cntg + 1);LL sum = 0, ans = 0;rep(i, 1, cntg) sum += getl[i].r - getl[i].l;rep(i, 1, cntg - 1) val[i] = getl[i+1].r - getl[i].l;sort(val + 1, val + cntg), reverse(val + 1, val + cntg);dwn(i, cntg - 1, K) sum -= val[i];rep(i, cntg + 1, K) sum += bigl[i-cntg].r - bigl[i-cntg].l;int cg, cb;if(cntg <= K) cg = cntg, cb = K - cntg;else cg = K, cb = 0;ans = max(ans, sum);for(; cg > 1;) {sum -= val[--cg];cb++; sum += bigl[cb].r - bigl[cb].l;ans = max(ans, sum);}sum = 0;sort(ls + 1, ls + n + 1, cmplen);rep(i, 1, K - 1) sum += ls[i].r - ls[i].l;printf("%lld\n", max(ans, sum));return 0;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8323454.html

2018冬令营模拟测试赛(十九)相关推荐

  1. 2018冬令营模拟测试赛(九)

    2018冬令营模拟测试赛(九) [Problem A]王子 试题描述 不是所有王子都会遇见自己的中关村,主公,公主. 从前有个王子姓王,王王子遇到了一位美丽的公主,她的名字当然是公公主啦. 王王子对公 ...

  2. 2018冬令营模拟测试赛(十八)

    2018冬令营模拟测试赛(十八) [Problem A]Table 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述&qu ...

  3. 2018冬令营模拟测试赛(一)

    2018冬令营模拟测试赛(一) [Problem A]全面战争不可避 试题描述 补充说明:铁路毁坏指的是这条铁路彻底消失了,不会对之后的询问造成影响(即询问之间是独立的) 输入 输出 输入示例1 5 ...

  4. NOI2021模拟测试赛 解题报告

    (一) A 暴力:求出所有直线的解析式,对于每个点枚举所有直线看是否经过该点 优化:分块.关键是分块方式,这里是把平面分成sqrt(n)*sqrt(n)块 实现细节: 1.vector直接开二维来表示 ...

  5. [补档]noip2019集训测试赛(九)

    因为这次考试我一道题都不会,所以先不写了 转载于:https://www.cnblogs.com/youddjxd/p/11442143.html

  6. 2016北京集训测试赛(九)Problem C: 狂飙突进的幻想乡

    Solution 我们发现, 对于一条路径来说, 花费总时间为\(ap + q\), 其中\(p\)和\(q\)为定值. 对于每个点, 我们有多条路径可以到达, 因此对于每个区间中的\(a\)我们可以 ...

  7. 29、数据结构笔记之二十九数组之硬币抛掷模拟

    29.数据结构笔记之二十九数组之硬币抛掷模拟 "人生是各种不同的变故.循环不已的痛苦和欢乐组成的.那种永远不变的蓝天只存在于心灵中间,向现实的人生去要求未免是奢望.-- 巴尔扎克" ...

  8. 【软考软件评测师】第二十九章 可靠性可用性测试

    [软考软件评测师]第二十九章 可靠性可用性测试 [软考软件评测师]第二十九章 可靠性可用性测试 [软考软件评测师]第二十九章 可靠性可用性测试 第一部分知识点集锦 1.可靠性测试 1)主要活动 2)考 ...

  9. 华为虚拟服务器lanip地址,2018软考网络工程师《华为基础实验》十九配置路由器为DHCPServer...

    原标题:2018软考网络工程师<华为基础实验>十九配置路由器为DHCPServer 实验要求: 在R1上使能DHCP 功能. 创建三个全局地址池,用于为三个不同部门的PC分配IP 地址. ...

  10. 蓝桥杯单片机学习过程记录(二十九)第八届国赛超声波测距机

    蓝桥杯单片机学习过程记录(二十九)第八届国赛超声波测距机 题目如下: 已完成 应用的内容: EEPROM. 定时器.数码管 led灯,独立按键 DA电压输出 超声波测距 /* ------------ ...

最新文章

  1. 不要通过终止进程的方式清理内存
  2. jquery.zSlide.js-基于CSS3/HTML5演示文档jQuery插件
  3. 通过反射获取无参无返回值成员方法并使用
  4. 【Boost】boost库中thread多线程详解13——线程标识符
  5. c语言怎么让字母倒序排列尼,如何倒序单词顺序输出 ? 我是没辙了
  6. 数据结构:线性数据结构(4)-列表(栈,队列,deques, 列表)
  7. linux rsync删文件速度,Linux下使用rsync最快速删除大量文件的方法
  8. springboot thymeleaf 引入jquery_超详细实战:SpringBoot高级之autoconfigure自动化配置
  9. Json转化的三种方式
  10. docker使用_Docker的基本使用
  11. 单片机课程设计:基于STM32智能交通灯的设计
  12. 福建省小学四年级上册计算机知识点总结,小学四年级上册数学知识点大全【1-6单元】...
  13. Java习题练习:杨辉三角
  14. 【shaderforge学习笔记】 Parallax节点(视差节点)
  15. dual_arm2_ws(version1.0.0)编译问题
  16. python常用的案例
  17. windows客户端开发--也许是一条不归路
  18. 家乐福计算机管理与控制系统,家乐福的订货部门是整个家乐福物流系统的核心,控制整个企业的物流运转。在家乐福..._考试资料网...
  19. 反三角函数在matlab中怎样定义
  20. 用户登录查全表好还是用用户名好_白杨SEO:长尾关键词挖掘工具哪个好?5118站长工具功能大全看这...

热门文章

  1. go实现零停机重启和代码升级endless
  2. python语言由psf组织所有、这是一个商业组织_智慧职教云课堂APP店长实务答案搜题公众号...
  3. Godaddy域名push教程(域名转出教程)
  4. java计算两个时间差的方法_java计算两个时间相差天数的方法汇总
  5. Java 他们每人单独过桥的时间是_java实现 n人过桥问题
  6. 微信小程序html的font-size,字体大小(font-size)
  7. 浏览网站ssl证书错误该怎么办?
  8. 06 ElasticSearch模板搜索
  9. MPB:南土所褚海燕组-​​利用种分布模型绘制微生物分布图谱
  10. GitLab合并出现 “Ready to be merged automatically” 提示