博主水平不高, 只能打完$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. yii添加验证码 和重复密码

    <?phpnamespace frontend\models; use common\models\User;use yii\base\Model;use Yii; /** * Signup f ...

  2. Failure [INSTALL_CANCELED_BY_USER]

    安装app到真机,遇到 Failure [INSTALL_CANCELED_BY_USER] 错误. 解决方法:将手机的USB安装权限打开即可.设置->更多设置->开发者选项->US ...

  3. js 中的原型链与继承

    ECMAScript中将原型链作为实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 1.原型链 先回忆一下构造函数和原型以及实例的关系:每个构造函数都有一个原型对 ...

  4. 解题7(FindFirstOnlyOne)

    题目描述 找出字符串中第一个只出现一次的字符 输入描述: 输入一个非空字符串 输出描述: 输出第一个只出现一次的字符,如果不存在输出-1 示例1 输入 asdfasdfo 输出 o 代码如下: pac ...

  5. char和varchar查询速度、存储空间比较详解(转)

    转:http://tech.diannaodian.com/dw/data/sql/2011/1005/135572.html 一.数据行结构 1.char(n): 系统分配n个字节给此字段,不管字段 ...

  6. CSS垂直翻转/水平翻转提高web页面资源重用性

                    /*水平翻转*/ .flipx {     -moz-transform:scaleX(-1);     -webkit-transform:scaleX(-1);   ...

  7. hbase备份数据与异地新建

    hbase org.apache.hadoop.hbase.mapreduce.Driver export news /tmp/news1 备份news表至hdfs的/tmp目录下面. hadoop ...

  8. zabbix监控常见系统报错

    CPU触发器:1)Processor load is too high on {HOST.NAME} {HOST.NAME}上处理器负载太高触发器表达式:{Zabbix server:system.c ...

  9. Allowing GPU memory growth

    By default, TensorFlow maps nearly all of the GPU memory of all GPUs (subject to CUDA_VISIBLE_DEVICE ...

  10. 让Ubuntu可以压缩/解压缩RAR文件

    ubuntu刚安装的时候是不能解压rar文件的,只有在安装了解压工具之后,才可以解压. 安装:sudo apt-get install unrar卸载:sudo apt-get remove unra ...