博主水平不高, 只能打完$4$题, QAQ什么时候才能变强啊嘤嘤嘤


订正完6题了,  还想打今天下午的CF , 只能迟十分钟了, 掉分预定

A. Heist

输出 $max - min + n - 1$即可

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rd read()
using namespace std; const int N = 1e3 + ;
const int inf = ~0U >> ; int n, a[N], x, maxn, minn = inf; int read () {
int X = , p = ; char c = getchar();
for(; c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(; c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} int main()
{
n = rd;
for(int i = ; i <= n; ++i) {
a[i] = rd;
minn = min(minn, a[i]);
maxn = max(maxn, a[i]);
}
printf("%d\n", maxn - minn - n + );
}

Heist

B. Buying a TV Set

Description

要求找出 $ i<=a, j<=b$ 并且 $ i : j = x : y$

Solution

先将$ x, y$约分, 输出$ \min(i \div x, j \div y)$ 即可

Code

 #include<cstdio>
#define ll long long ll gcd(ll x, ll y) {
return x % y ? gcd(y, x % y) : y;
} int main()
{
ll a, b, x, y, d;
scanf("%I64d%I64d%I64d%I64d", &a, &b, &x, & y);
d = gcd(x, y);
x /= d; y /= d;
ll tmp1 = a / x, tmp2 = b / y;
printf("%I64d\n", tmp1 > tmp2 ? tmp2 : tmp1);
}

Buying a TV set

C. Coffee Break

Description

主人公想要在$n$个时间点喝咖啡, 但是老板要求他 每次 喝咖啡 的 间隔 必须 $>=d$

求问主人公至少要 几天 才能在 每个时间点 都喝过咖啡。

Solution

贪心 + 二分查找

用Set写 复杂度更严格, 但是我没想到用Set删除。

外层枚举到每一天$i$, 如果 $i$ 没有被确定在哪一天喝, 则 $++ans$, 并在第 $ans$(当前的ans) 天喝。

接下来再查找出第一个$>= \  a[i] + d + 1$的 时刻$j$,  如果$j$ 已经被确定在哪天喝, 那么$j++$, 直到$j > n $ 或 $j$ 没有被确定在哪一天喝。

把 $j$ 和 $i$ 确定为同一天喝就可以惹。

复杂度并不是严格的$O(nlogn)$, 希望不要呱

Code

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rd read()
using namespace std; const int N = 2e5 + ; int n, m, d, ans;
int b[N]; struct node {
int pos, id, day;
}a[N]; int read() {
int X = , p = ; char c =getchar();
for(;c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(;c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} int fd(int x) {
return lower_bound(b + , b + + n, x) - b;
} int cmp1(const node &A, const node &B) {
return A.pos < B.pos;
} int cmp2(const node &A, const node &B) {
return A.id < B.id;
} int main()
{
n = rd; m = rd; d = rd;
for(int i = ; i <= n; ++i)
b[i] = a[i].pos = rd, a[i].id = i;
sort(b + , b + + n);
sort(a + , a + + n, cmp1);
for(int i = ; i <= n; ++i) {
if(!a[i].day) a[i].day = ++ans;
int tmp = a[i].pos + d + ;
tmp = fd(tmp);
while(a[tmp].day && tmp <= n)
tmp++;
if(tmp <= n) a[tmp].day = a[i].day;
}
printf("%d\n", ans);
sort(a + , a + + n, cmp2);
printf("%d", a[].day);
for(int i = ; i <= n; ++i)
printf(" %d", a[i].day);
puts("");
}

Coffee Break

D. Glider

Description

求出从哪一点开始下飞机, 滑翔的水平距离最远。 在上升气流的区间内 水平飞行, 在其他地方会 $1 : 1$地 下降

并且输入的 上升气流的区间不重合、且递增。

Solution

官方题解 二分 + 前缀和

我打出了个倍增。。。

定义$nxt[i][j]$ 为 $i$ 之后的 第 $2^j$ 个区间(这不是可以直接$O(1)$算吗??? 我怎么知道我当时怎么想的。。。

$dis[i][j]$ 为 $i$ 到 之后第 $2 ^ j$ 个区间 的空隙长度(即没有上升气流的长度)。

  $sum[i] $为前 $i$ 个上升气流的总长度

由于空隙长度 必须 $ <= \ h$, 所以可以倍增求出最远到哪个区间。

然后枚举下飞机的区间, 倍增求出最远到达的区间, 前缀和查询 上升气流长度 并更新答案。

Code

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rd read()
using namespace std; const int N = 2e5 + ;
const int base = ; int l[N], r[N], h, n, maxn = h, sum[N];
int dis[N][], nxt[N][]; int read() {
int X = , p = ; char c = getchar();
for(;c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(; c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} void cal(int now) {
int rest = h, tmp = now;
for(int k = base; ~k; --k)
if(nxt[tmp][k] && rest - dis[tmp][k] > )
rest -= dis[tmp][k], tmp = nxt[tmp][k];
maxn = max(maxn, h + sum[tmp] - sum[now - ]);
} int main()
{
n = rd; h = rd;
for(int i = ; i <= n; ++i)
l[i] = rd, r[i] = rd;
for(int i = ; i <= n; ++i)
sum[i] = sum[i - ] + r[i] - l[i];
for(int i = ; i < n; ++i) {
dis[i][] = l[i + ] - r[i];
nxt[i][] = i + ;
}
for(int k = ; k <= base; ++k)
for(int i = ; i <= n; ++i) {
nxt[i][k] = nxt[nxt[i][k - ]][k - ];
dis[i][k] = dis[i][k - ] + dis[nxt[i][k - ]][k - ];
}
for(int i = ; i <= n; ++i) cal(i);
printf("%d\n", maxn);
}

Glider

之后的就不会噜


upd

订正了一波。

E. Tree Reconstruction

Solution

显然, 输入中的 $b$ 肯定等于$N$, 否则就一定不存在这样的一棵树。

对于每个节点 $i$ $(i < n)$ , 它在输入中出现的次数为 $cnt[i]$, 那么 对于每个 $k$ , $cnt[1] \ + cnt[2] \ ... \ + cnt[k] \ <= k$ , 否则就不存在。

然后就构造一条链, 一端是$N$, 另一端通过算法来补全。

依次枚举$i$, 如果$cnt[i] \ == \ 0$, 那么把它继续留在$Set$里面, 到之后用。

如果$cnt[i] \ > \ 0$, 那么 把 $i$ 添到链中, 因为在 $i$ 之前添入链中的节点编号都 $ < \ i$, 也就是对 $i$ 不产生贡献。

  接着往 链中添入 $cnt[i] \ - \ 1$ 个节点(这些节点的编号可以保证都 $< \ i$) 。

枚举结束后再将 $N$ 与最后一个添入的节点连边

Code

 #include<cstdio>
#include<cstring>
#include<set>
#define rd read()
using namespace std; const int N = 1e5 + ; int cnt[N], n; set<int>st; int read() {
int X = , p = ; char c = getchar();
for(;c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(;c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} int main()
{
n = rd;
for(int i = ; i < n; ++i) {
int u = rd, v = rd;
if(v != n) return puts("NO"), ;
cnt[u]++;
}
int cur = ;
for(int i = ; i < n; ++i)
if((cur += cnt[i]) > i)
return puts("NO"), ;
for(int i = ; i < n; ++i)
st.insert(i);
puts("YES");
int last = ;
for(int i = ; i < n; ++i) {
if(cnt[i]) {
st.erase(i);
if(last)
printf("%d %d\n", last, i);
cnt[i]--;
last = i;
}
while(cnt[i]) {
printf("%d %d\n", last, *st.begin());
last = *st.begin();
cnt[i]--;
st.erase(*st.begin());
}
}
printf("%d %d\n", last, n);
}

Tree Reconstruction

F. Ray in the tube

感觉题解写的非常靠谱|清楚 , 题解传送门

Solution

设$A,  B$ 两点的水平距离为 $d$

要使传感器感应到同一条光, 那么就要满足

在第一条线上 : $a_i \ = \ a_j (mod \ 2d)$

在第二条线上:  $b_i \ = \ b_j = a_k \ + \ d \ (mod \  2d)$( $a$ 表示第一条线上的点, $b$ 表示第二条线上的点)

有一个神奇的结论: 要使其方案最优, 必定有$d \ = \ 2^i$ $(i \ >= \ 0$)。

反证 : 假如 $ d \ = \ k \ * \ 2^i$ ($k$ 为奇数), 那么它到达的点, $2^i$ 同样也能到达, 并且$2^i$ 所能到达的点更多。

然后我们就枚举$d$ ($log1e9$种可能), 用 $MAP$ 记录 $a_i \ mod \ 2d$, 和 $(b_i \ + d) \ mod \ 2d$, 并在记录中更新答案。

总复杂度 $O(NlogNlog1e9)$

Code

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define rd read()
using namespace std; const int N = 1e5 + ; map<int, int> M; int a[N], b[N], n, m, maxn = ; int read() {
int X = , p = ; char c = getchar();
for(; c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(; c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} int main()
{
n = rd; rd;
for(int i = ; i <= n; ++i)
a[i] = rd;
m = rd; rd;
for(int i = ; i <= m; ++i)
b[i] = rd;
for(int tmp = ; tmp <= 1e9; tmp <<= ) {
M.clear();
for(int i = ; i <= n; ++i) {
int k = a[i] % (tmp << );
if(!M.count(k)) M[k] = ;
else {maxn = max(maxn, ++M[k]);}
}
for(int i = ; i <= m; ++i) {
int k = (1LL * b[i] + tmp) % (tmp << );
if(!M.count(k)) M[k] = ;
else {maxn = max(maxn, ++M[k]);}
}
}
printf("%d\n", maxn);
}

Ray in the tube

codeforces round#509的更多相关文章

  1. Codeforces Round #509 (Div. 2) F. Ray in the tube(思维)

    题目链接:http://codeforces.com/contest/1041/problem/F 题意:给出一根无限长的管子,在二维坐标上表示为y1 <= y <= y2,其中 y1 上 ...

  2. Codeforces Round #509 (Div. 2) E. Tree Reconstruction(构造)

    题目链接:http://codeforces.com/contest/1041/problem/E 题意:给出n - 1对pair,构造一颗树,使得断开其中一条边,树两边的最大值为 a 和 b . 题 ...

  3. Codeforces Round #509 (Div. 2)

    咕咕咕了好多天终于有时间写篇博客了_(:з」∠)_ 打网赛打到自闭的一周,终于靠这场CF找回了一点信心... 1041A - Heist \(ans=max\left \{ a_i \right \} ...

  4. codeforces 1041d// Glider// Codeforces Round #509(Div. 2)

    题意:给出,n和飞行员高度h,n是区间数.在区间里飞行员高度不变,其它地方每秒高度-1,x坐标+1.问在高度变为0以前,x坐标最多加多少? 用数组gap记录本区间右端到下一个区间左端的距离.用sum记 ...

  5. Codeforces Round#509 Div.2翻车记

    A:签到 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  6. Codeforces Round #509 (Div. 2) A. Heist 贪心

    There was an electronic store heist last night. All keyboards which were in the store yesterday were ...

  7. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  8. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  9. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

随机推荐

  1. MD5 算法

    MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321(R. ...

  2. pandas 常用清洗数据(二)

    1. df.head() Here we import pandas using the alias 'pd', then we read in our data. df.head - shows u ...

  3. centos 6.x系统升级glibc库至2.15版本的快速解决办法

    CentOS 6.x系统升级glibc库至2.15版本的快速解决办法  1.先确保相关软件包已经安装 yum install -y glibc yum install -y glibc-common ...

  4. python3使用paramiko操作远程机器

    目标:有A和B两台机器,希望在机器A上操作B上的脚本   解决方法:使用paramiko实现操作远程机器   1.安装paramiko   安装第三方包[pip3 install paramiko] ...

  5. Windows消息循环

    首先理解一句话:“Windows”向应用程序发送了一条消息.这里是指Windows调用了该程序内部的一个函数. 当UpdateWindow被调用后,新建的窗口在屏幕便完全可见了.此时,Windows会 ...

  6. java面试题:Linux

    Q:Linux怎么查端口?端口被占用怎么办? netstat -ntulp | grep 2181//查看2181端口号 netstat -pan | grep 2181 //查看2181端口号 如下 ...

  7. centos7安装zabbix3.5

    安装centos7 自带MariaDB数据库(或者安装mysql) yum -y install mariadb-server mariadb-devel systemctlstartmariadb. ...

  8. Failed to start LSB: Bring up/down networking 问题

    Failed to start LSB: Bring up/down networking 问题   1.执行 service network restart 出现以下错误 Restarting ne ...

  9. Centos + Maven + Jenkins

    下载 JDKwget --no-check-certificate --no-cookie --header "Cookie: oraclelicense=accept-secureback ...

  10. MDK生成.bin

    方法1: 默认选择编译输出的路径输出bin fromelf.exe --bin -o "$L@L.bin" "#L" 保存编译 方法2: 在要输出的目录下,新建 ...