2019-08-23 纪中NOIP模拟A组
T1 [JZOJ2908] 矩阵乘法
题目描述
给你一个 N*N 的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第 K 小数。
数据范围
对于 $20\%$ 的数据,$N \leq 100$,$Q \leq 10^3$
对于 $40\%$ 的数据,$N \leq 300$,$Q \leq 10^4$
对于 $60\%$ 的数据,$N \leq 400$,$Q \leq 3 \times 10^4$
对于 $100\%$ 的数据,$N \leq 500$,$Q \leq 6 \times 10^4$
分析
作为一个数据结构菜鸡怎么可能会做这种题目
本题有多种写法我都写不来,代码中给出是二维树状数组+整体二分,此外还有主席树+分块没学过啊,等等
基于划分树的边二分边查询的思想,我们可以二分所有询问,一开始二分同样的一个数值,即查询一个子矩形中小于等于 $mid$ 的数的个数,这里用二维树状数组进行统计
二分后所有节点会分成两边,只需要将所有询问与矩阵中的数字分别递归即可
时间复杂度为 $O((q+n^2) \, log^2 n \, log \, q)$
实际上由于二维树状数组的常数非常小,所以这个算法是可以通过的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
#define N 502
#define M 60005 inline int read() {
int x = , f = ; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -; ch = getchar();}
while ( isdigit(ch)) {x = x * + ch - ''; ch = getchar();}
return x *= f;
} int n, m, t[N][N];
int id[M], cur[M], ans[M], q1[M], q2[M]; struct Mat {int x, y, v;} g[N * N];
bool cmp(Mat a, Mat b) {return a.v < b.v;}
struct Query {int x1, y1, x2, y2, k;} q[M]; inline int lowbit(int x) {return x & -x;} inline void add(int x, int y, int v) {
for (int i = x; i <= n; i += lowbit(i))
for (int j = y; j <= n; j += lowbit(j))
t[i][j] += v;
} inline int pre(int x, int y) {
int sum = ;
for (int i = x; i; i -= lowbit(i))
for (int j = y; j; j -= lowbit(j))
sum += t[i][j];
return sum;
} inline int sub(int x1, int y1, int x2, int y2) {
int sum = pre(x2, y2);
sum -= pre(x1 - , y2) + pre(x2, y1 - );
sum += pre(x1 - , y1 - );
return sum;
} void solve(int l, int r, int ql, int qr) {
if (ql > qr) return;
if (l == r) {
for (int i = ql; i <= qr; i++) ans[id[i]] = g[l].v;
return;
}
int mid = (l + r) >> , cnt1 = , cnt2 = ;
for (int i = l; i <= mid; i++) add(g[i].x, g[i].y, );
for (int i = ql, j = id[i]; i <= qr; j = id[++i]) {
int sum = cur[j] + sub(q[j].x1, q[j].y1, q[j].x2, q[j].y2);
if (sum >= q[j].k) q1[++cnt1] = j;
else q2[++cnt2] = j, cur[j] = sum;
}
int cnt = ql - ;
for (int i = ; i <= cnt1; i++) id[++cnt] = q1[i];
for (int i = ; i <= cnt2; i++) id[++cnt] = q2[i];
for (int i = l; i <= mid; i++) add(g[i].x, g[i].y, -);
solve(l, mid, ql, ql + cnt1 - );
solve(mid + , r, ql + cnt1, qr);
} int main(){
n = read(); m = read();
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++) {
g[(i - ) * n + j].x = i;
g[(i - ) * n + j].y = j;
g[(i - ) * n + j].v = read();
}
sort(g + , g + n * n + , cmp);
for (int i = ; i <= m; i++) {
q[i].x1 = read(); q[i].y1 = read();
q[i].x2 = read(); q[i].y2 = read();
q[i].k = read(); id[i] = i;
}
solve(, n * n, , m);
for (int i = ; i <= m; i++)
printf("%d\n", ans[i]); return ;
}
T2 [JZOJ3410] Tree
题目描述
Wayne 在玩儿一个很有趣的游戏。在游戏中,Wayne 建造了 N 个城市,现在他想在这些城市间修一些公路,当然并不是任意两个城市间都能修,为了道路系统的美观,一共只有 M 对城市间能修公路,即有若干三元组 (Ui, Vi,Ci) 表示 Ui 和 Vi 间有一条长度为 Ci 的双向道路。当然,游戏保证了,若所有道路都修建,那么任意两城市可以互相到达。
Wayne 拥有恰好 N - 1 支修建队,每支队伍能且仅能修一条道路。当然,修建长度越大,修建的劳累度也越高,游戏设定是修建长度为 C 的公路就会有 C 的劳累度。当所有的队伍完工后,整个城市群必须连通,而这些修建队伍们会看看其他队伍的劳累情况,若劳累情况差异过大,可能就会引发骚动,不利于社会和谐发展。Wayne 对这个问题非常头疼,于是他想知道,这 N - 1 支队伍劳累度的标准差最小能有多少。
数据范围
对于 $20\%$ 的数据,$M \leq 20$
对于另外 $30\%$ 的数据,$C \leq 10$
对于 $100\%$ 的数据,$N \leq 100$,$M \leq 2000$,$C \leq 100$
分析
考场上写了个水法,后来发现似乎是正解喜闻乐见
首先这是一道最小标准差生成树
刚开始发现 $C$ 很小,感觉解法和这个有关,于是想到枚举平均数
但是直接枚举出平均数是不存在的,考虑到标准差是个表示数据稳定性的量,所以可以在合理范围内枚举长度值,选取长度与之最接近的道路做生成树,然后算出真实平均值求标准差来更新答案
由于所有道路的长度都是正整数,所以对于 $x \in (0.5k,0.5k+0.5) \; (k \in N)$,当 $k$ 取某固定值时,无论 $x$ 取何值,所有道路按长度与 $x$ 的差值从小到大排序的结果是相同的
因此只需要每隔 $0.25$ 枚举一个长度值,当然也可以将所有道路长度都乘以 $4$
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 105
#define M 2005 inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') {if (ch == '-') f = -; ch = getchar();}
while (ch >= '' && ch <= '') {x = x * + ch - ''; ch = getchar();}
return x *= f;
} double ans = 1000000000.0;
int n, m, maxe, mine = inf;
int f[N], q[N]; struct Edge {int u, v, w, d;} e[M];
bool cmp(Edge a, Edge b) {return a.d < b.d;} int find(int x) {
if (x == f[x]) return x;
return f[x] = find(f[x]);
} int main() {
n = read(); m = read();
for (int i = ; i <= m; i++) {
e[i].u = read(); e[i].v = read(); e[i].w = read() * ;
maxe = max(maxe, e[i].w); mine = min(mine, e[i].w);
}
for (int k = mine; k <= maxe; k++) {
for (int i = ; i <= m; i++) e[i].d = abs(e[i].w - k);
sort(e + , e + m + , cmp);
int cnt = , sum = ; double now = ;
for (int i = ; i <= n; i++) f[i] = i;
for (int i = ; i <= m; i++) {
int x = find(e[i].u), y = find(e[i].v);
if (x == y) continue; f[x] = y;
q[++cnt] = i; sum += e[i].w / ;
if (cnt == n - ) break;
}
double avg = (double)sum / (double)(n - );
for (int i = ; i < n; i++)
now += (e[q[i]].w / 4.0 - avg) * (e[q[i]].w / 4.0 - avg);
now = sqrt(now / (n - ));
ans = min(ans, now);
}
printf("%.4lf", ans); return ;
}
T3 [JZOJ3682] Points and Segments
题目描述
Lahub 在几何问题上准备得不充分,但是他听说这一年的 IOI 选拔夏令营中会出现许多几何问题。深陷恐惧的 Lahub 把他自己锁在了地下室里,并且开始思考这一类别的新题目。其中一个如下。
Lahub 想要在 OX 轴上画 n 条不同的线段 [li,ri]。线段可以是红色和蓝色其中任意一种。图画是“好”的当且仅当满足接下来的条件:
对于每个 OX 轴上的点 x,考虑所有包含点 x 的线段,设有 rx 个红线段和 bx 个蓝线段包含点 x,必须满足不等式 |rx-bx|<=1。
线段 [l,r] 包含点 x 当且仅当 l<= x<= r。
Lahub 给你所有线段的左右端点,你不得不找到一个“好”的画法给他。
数据范围
对于 $20\%$ 的数据,$N \leq 10$
对于 $40\%$ 的数据,$N \leq 10^3$
对于 $100\%$ 的数据,$N \leq 10^5$
分析
根据差分的思想,一段区间被染色,就相当于 $l$ 加,$r+1$ 减
首先当然要把点离散化,然后对于每个区间我们可以在 $l$ 和 $r+1$ 之间连一条无向边
如果图中存在奇点(一定为偶数个),则可以从小到大组成若干对点,在每对点之间连一条虚边(任意两条虚边之间不存在重合部分),此时就形成了一个欧拉回路
于是可以在图上跑一边欧拉回路,若经过某条边时方向向左,则对应区间被染成红色,反之则被染成蓝色,这样就能保证在每个点上红色和蓝色的覆盖次数之差的绝对值不超过 $1$
因为这是个欧拉回路,覆盖每个点的红色区间和蓝色区间数量一定相等,且每个点最多被一条虚边覆盖,所以删去虚边后仍然符合题意
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
#define inf 0x3f3f3f3f
#define N 200005 inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') {if (ch == '-') f = -; ch = getchar();}
while (ch >= '' && ch <= '') {x = x * + ch - ''; ch = getchar();}
return x *= f;
} int n, m, tot = , last;
int to[N << ], num[N << ], nxt[N << ], head[N];
int q[N], d[N], vis[N], used[N << ], ans[N >> ];
struct Data {int l, r;} t[N >> ]; void add(int u, int v, int w) {
to[++tot] = v; num[tot] = w;
nxt[tot] = head[u]; head[u] = tot;
} void dfs(int x) {
vis[x] = ;
for (int &i = head[x]; i; i = nxt[i])
if (!used[i]) {
used[i] = used[i ^ ] = ;
ans[num[i]] = (to[i] > x);
dfs(to[i]);
}
} int main(){
n = read();
for (int i = ; i <= n; i++) {
t[i].l = read(); t[i].r = read() + ;
q[++m] = t[i].l; q[++m] = t[i].r;
}
sort(q + , q + m + );
m = unique(q + , q + m + ) - q - ;
for (int i = ; i <= n; i++) {
t[i].l = lower_bound(q + , q + m + , t[i].l) - q;
t[i].r = lower_bound(q + , q + m + , t[i].r) - q;
add(t[i].l, t[i].r, i); add(t[i].r, t[i].l, i);
d[t[i].l]++; d[t[i].r]++;
}
for (int i = ; i <= m; i++)
if (d[i] & ) {
if (last) {
add(last, i, ); add(i, last, );
d[last]++; d[i]++; last = ;
}
else last = i;
}
for (int i = ; i <= m; i++) if (!vis[i]) dfs(i);
for (int i = ; i <= n; i++) printf("%d ", ans[i]); return ;
}
2019-08-23 纪中NOIP模拟A组的更多相关文章
- 2019-08-21 纪中NOIP模拟A组
T1 [JZOJ6315] 数字 题目描述
- 2019-08-09 纪中NOIP模拟B组
T1 [JZOJ1035] 粉刷匠 题目描述 windy有N条木板需要被粉刷. 每条木板被分为M个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一 ...
- 2019-08-15 纪中NOIP模拟B组
T1 [JZOJ3455] 库特的向量 题目描述 从前在一个美好的校园里,有一只(棵)可爱的弯枝理树.她内敛而羞涩,一副弱气的样子让人一看就想好好疼爱她.仅仅在她身边,就有许多女孩子想和她BH,比如铃 ...
- 2019-08-12 纪中NOIP模拟B组
T1 [JZOJ4879] 少女觉 题目描述 “在幽暗的地灵殿中,居住着一位少女,名为古明地觉.” “据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力——读心.” “掌控人心者,可控 ...
- 2019-08-01 纪中NOIP模拟B组
T1 [JZOJ2642] 游戏 题目描述 Alice和Bob在玩一个游戏,游戏是在一个N*N的矩阵上进行的,每个格子上都有一个正整数.当轮到Alice/Bob时,他/她可以选择最后一列或最后一行,并 ...
- 2019-08-25 纪中NOIP模拟A组
T1 [JZOJ6314] Balancing Inversions 题目描述 Bessie 和 Elsie 在一个长为 2N 的布尔数组 A 上玩游戏. Bessie 的分数为 A 的前一半的逆序对 ...
- 2019-08-20 纪中NOIP模拟B组
T1 [JZOJ3490] 旅游(travel) 题目描述 ztxz16如愿成为码农之后,整天的生活除了写程序还是写程序,十分苦逼.终于有一天,他意识到自己的生活太过平淡,于是决定外出旅游丰富阅历. ...
- 2019-08-20 纪中NOIP模拟A组
T1 [JZOJ6310] Global warming 题目描述 给定整数 n 和 x,以及一个大小为 n 的序列 a. 你可以选择一个区间 [l,r],然后令 a[i]+=d(l<=i< ...
- 2019-08-18 纪中NOIP模拟A组
T1 [JZOJ6309] 完全背包 题目描述
随机推荐
- light oj 1045 - Digits of Factorial K进制下N!的位数
1045 - Digits of Factorial Factorial of an integer is defined by the following function f(0) = 1 f(n ...
- 【React Native】某个页面禁用物理返回键
1.引入组件 import { BackHandler, } from 'react-native'; 2.添加监听 componentDidMount(): void { BackHandler.a ...
- ACP知识总结
由于ACP是一个敏捷开发的系统性知识,下面只针对我自身学习的知识总结,若需要完整的考试学习资料,可评论区或私聊我拿. 敏捷估计与规划.png ACP知识点锦集.png 敏捷项目软件总结.p ...
- mysql设置编码格式--支持中文
创建table的时候就使用utf8编码 在每次创建表的时候都在最后加上 character set = utf8就可以很好的支持中文 create table xxx ( id int auto_in ...
- 高性能异步SRAM技术角度
当前有两个不同系列的异步SRAM:快速SRAM(支持高速存取)和低功耗SRAM(低功耗).从技术角度看来,这种权衡是合理的.在低功耗SRAM中,通过采用特殊栅诱导漏极泄漏(GIDL)控制技术控制待机电 ...
- Java连载88-HashSet集合与hashCode方法重写
一.Set集合 1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构. 2.哈希表又称为散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链 ...
- Linux服务器被入侵后的处理过程(转发阿良)
Linux服务器被入侵后的处理过程 突然,频繁收到一组服务器 ping 监控不可达邮件,赶紧登陆 zabbix 监控系统查看流量状况. 可见流量已经达到了 800M 左右,这肯定不正常了,马上尝试 ...
- 《自拍教程21》mediainfo_多媒体文件查看工具
mediainfo命令介绍 mediainfo.exe(Linux/iMac下是未带后缀的mediainfo), 是一款音视频图片文件的信息查询工具, 常用于查看多媒体文件的视频流信息,音频流信息,字 ...
- position定位及实际应用
position: static; 静态定位 / 常规定位 / 自然定位 忽略top/right/bottom/left/z-index的影响,使元素回到自然流中 <!DOCTYPE html ...
- 用友UAP NC 开发环境抛出"JDK默认编辑器找不到"
此节点是升级65之前开发的,已经很久不使用,今天在开发环境使用,点查询抛出此异常. 最后问了人解决方法,就是往JRE系统库加入对应的jar包