由于我的codeforces的帐号登不上,所以我错过了这场比赛,只好赛后再抄题解自己做。

A Benches

最大的情况就是所有人都挤在那个人最多的长椅上,最小的情况是所有人尽量平均的坐。

#include <cstdio>
#include <cstring>
#include <algorithm> const int N = 110; int a[N], n, m, mx; int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
mx = std::max(a[i], mx);
}
int ansb = mx + m, ansa = 0;
for (int i = 1; i <= n; ++i) {
m -= mx - a[i];
}
if (m < 0) ansa = mx;
else ansa = mx + m / n + (m%n != 0);
printf("%d %d\n", ansa, ansb);
return 0;
}

提交次数:\(1\)

B Vitamins

这个题直接DP,把有哪几种维他命状压一下就行。

#include <cstdio>
#include <cstring>
#include <algorithm> const int N = 1010; int V[N];
int n, c[N], p[N];
int f[10]; int main() {
V['A'] = 1; V['B'] = 2; V['C'] = 4;
scanf("%d", &n);
char s[5];
for (int i = 1; i <= n; ++i) {
scanf("%d%s", &p[i], s);
int len = strlen(s);
for (int j = 0; j < len; ++j) c[i] |= V[s[j]];
}
memset(f, 0x3f, sizeof f);
f[0] = 0;
for (int i = 1; i <= n; ++i) {
for (int S = 7; S >= 0; --S) if (f[S] < 0x3f3f3f3f) {
f[S|c[i]] = std::min(f[S|c[i]], f[S] + p[i]);
}
}
if (f[7] == 0x3f3f3f3f) puts("-1");
else printf("%d\n", f[7]);
return 0;
}

提交次数:\(1\)

C Array Product

这个也是一个简单的构造题,贪心的做就行,不要忘记只能删除一个点。

删正数肯定是不优的。如果有偶数个负数,乘起来就行,如果有奇数个负数,将绝对值最小的负数和0乘起来(如果没有0那就直接删),然后把所有0乘起来删掉(如果就只剩一个0了那就不能删)。

最后把所有数乘起来就行。

#include <cstdio>
#include <cstring>
#include <algorithm> const int N = 2e5 + 10; int a[N], n, m, mx = 0, del[N], tot, posi, nega, zero;
int ls[3][N]; int main() {
scanf("%d", &n);
a[0] = -0x3f3f3f3f;
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
if (a[i] == 0) {
ls[1][++zero] = i;
} else if (a[i] < 0 ) {
ls[0][++nega] = i;
if (a[i] > a[mx]) mx = i;
} else {
ls[2][++posi] = i;
}
}
if (nega%2 != 0 && zero > 0) {
printf("1 %d %d\n", mx, ls[1][1]);
del[mx] = 1;
tot++;
} else if (nega%2 != 0 && zero == 0) {
printf("2 %d\n", mx);
del[mx] = 1;
tot++;
} if (zero > 0) {
while (zero > 1 && tot < n-2) {
printf("1 %d %d\n", ls[1][zero], ls[1][zero-1]);
del[ls[1][zero]] = 1;
zero--;
tot++;
}
if (tot < n-1) {
printf("2 %d\n", ls[1][1]);
tot++;
del[ls[1][1]] = 1;
}
}
int i = 1, j;
while (del[i]) i++;
j = i+1;
while (tot < n-1) {
while (del[j]) j++;
printf("1 %d %d\n", i, j);
i = j;
j = i+1;
tot++;
}
return 0;
}

提交次数:\(3\)(没看到只能删一次和少处理了一个情况)。

D Petya and Array

求区间和一定要求前缀和,然后问题就转化成了求\(\displaystyle\sum_{l}\displaystyle\sum_{r}[s_i-s_{l-1}<k]\),化简一下就成了\(\displaystyle\sum_{l}\displaystyle\sum_{r}[s_i<k+s_{l-1}]\),直接倒着做然后树状数组查就行。别忘了离散化的时候要把\(S_0 = 0\)也离散进去(并没有想明白为什么)

#include <cstdio>
#include <algorithm> const int N = 200000 + 10;
typedef long long LL; LL a[N], s[N], b[N], c[N];
LL t;
int n, mx;
LL bt[N]; inline void add(int x) {
for (; x <= mx; x += x&-x) {
bt[x]++;
}
} inline LL query(int x) {
LL ans = 0;
for (; x>0; x -= x&-x) {
ans += bt[x];
}
return ans;
} int main() {
scanf("%d%I64d", &n, &t);
for (int i = 1; i <= n; ++i) {
scanf("%I64d", &a[i]);
s[i] = s[i-1] + a[i];
b[i+1] = s[i];
}
std::sort(b+1, b+n+2);
mx = std::unique(b+1, b+n+2) - b - 1;
for (int i = 1; i <= n; ++i) {
c[i] = std::lower_bound(b+1, b+mx+1, s[i]) - b;
}
LL ans = 0;
for (int i = n; i; --i) {
add(c[i]);
int tmp = std::lower_bound(b+1, b+mx+1, s[i-1]+t) - b - 1;
ans += query(tmp);
}
printf("%I64d\n", ans);
return 0;
}

提交次数:\(5\)(离散化没加\(0\),和lower_bound上界写错)

E Vasya and Magic Matrix

这个题还是能轻松的想到排序后从小到大枚举计算的。只是我一开始没有看到欧式距离的平方,苦思无解,只好去看题解,结果……

有平方的话就有交换律和结合律了,某个点的期望值为\(f_x = \displaystyle\frac{\displaystyle\sum_{1\le i\le k}(f_i + (r_x-r_i)^2 + (c_x-c_i)^2)}{k}\),其中\(k\)是所有比他小的点的数量。化简之后就能发现这个式子只与比他小的数的个数,横纵坐标的和,横纵坐标的平方和,以及期望和有关。开几个变量记录一下就行(我图方便开了数组)

#include <cstdio>
#include <algorithm> typedef long long LL;
const int N = 1e3 + 10;
const int M = N*N;
const LL MOD = 998244353; struct node {
LL x, y, h;
bool operator< (const node &x) const {
return h < x.h;
}
} p[M];
int n, m, tot;
LL pos, sf[M], sx[M], sy[M], sx2[M], sy2[M], sk[M];
LL dp[N][N];
int x, y; inline LL pow_mod(LL x, LL p) {
LL ans = 1;
while (p) {
if (p&1) ans = ans * x % MOD;
x = x * x % MOD;
p = p >> 1;
}
return ans;
} int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
tot++;
scanf("%I64d", &p[tot].h);
p[tot].h++;
p[tot].x = i;
p[tot].y = j;
}
}
scanf("%d%d", &x, &y);
std::sort(p+1, p+tot+1);
for (int i = 1; i <= tot; ++i) {
if (p[i].h != p[i-1].h) {
pos++;
sf[pos] += sf[pos-1];
sx[pos] += sx[pos-1];
sy[pos] += sy[pos-1];
sx2[pos] += sx2[pos-1];
sy2[pos] += sy2[pos-1];
sk[pos] += sk[pos-1];
}
LL f = 0;
f = (f + sf[pos-1]) % MOD;
f = (f + sx2[pos-1]) % MOD;
f = (f + sy2[pos-1]) % MOD;
f = (f + p[i].x * p[i].x % MOD * sk[pos-1] % MOD) % MOD;
f = (f + p[i].y * p[i].y % MOD * sk[pos-1] % MOD) % MOD;
f = (f - 2 * p[i].x % MOD * sx[pos-1] % MOD + MOD) % MOD;
f = (f - 2 * p[i].y % MOD * sy[pos-1] % MOD + MOD) % MOD;
f = f * pow_mod(sk[pos-1], MOD-2) % MOD;
dp[p[i].x][p[i].y] = f;
sf[pos] = (sf[pos] + f) % MOD;
sx[pos] = (sx[pos] + p[i].x) % MOD;
sy[pos] = (sy[pos] + p[i].y) % MOD;
sx2[pos] = (sx2[pos] + p[i].x * p[i].x % MOD) % MOD;
sy2[pos] = (sy2[pos] + p[i].y * p[i].y % MOD) % MOD;
sk[pos] = (sk[pos] + 1) % MOD;
if (p[i].x == x && p[i].y == y) break;
}
printf("%I64d\n", dp[x][y]);
return 0;
}

提交次数:\(0+1\)

F Leaf Sets

这个题看了一会儿觉得不可做,就直接看了题解。

其实用了树形DP的思想,先dfs下去,再统计儿子们的答案然后上传。不过这个在dfs里开vector的操作惊到我了,我以前从未见过这样的写法(但是这样不会爆栈吗?)。

首先,对于一个叶子节点的集合,我们用这个集合中深度最大的点代表这个集合,因为只有这个点决定了两个集合能否合并。如果两个集合\(A,B\)的代表点\(d_A,d_B\)之间的距离小于\(k\),那就可以合并,且合并后代表点的深度为\(max\{ d_A, d_B \}\),如果大于\(k\)呢?不妨设\(d_A\le d_B\),此时\(d_B\)一定没有用了,因为之后能和\(B\)合并的也一定能和\(A\)合并,那么\(B\)集合就不用再合并了,直接记录答案就行。

#include <cstdio>
#include <algorithm>
#include <vector> const int N = 1e6 + 10;
const int M = 2e6 + 10; int n, k;
int hd[N], to[M], nxt[M], cnt;
int dep[N], deg[N];
int ans; inline void adde(int x, int y) {
cnt++;
to[cnt] = y;
nxt[cnt] = hd[x];
hd[x] = cnt;
} int dfs(int x, int f) {
if (deg[x] == 1) {
return 0; // 叶子直接返回0
}
std::vector<int> d;
for (int i = hd[x]; i; i = nxt[i]) if (to[i] != f) {
d.push_back(dfs(to[i], x) + 1);
}
std::sort(d.begin(), d.end());
while (d.size() >= 2) {
if (d[d.size()-1] + d[d.size()-2] <= k) break;
d.pop_back(); // 不能合并的就不合并了。
ans++;
}
return d.back(); // 相当于把d中的所有集合合并了。
} int main() {
scanf("%d%d", &n, &k);
for (int i = 1, x, y; i < n; ++i) {
scanf("%d%d", &x, &y);
adde(x, y);
adde(y, x);
deg[y]++; deg[x]++;
}
for (int i = 1; i <= n; ++i) if (deg[i] > 1) {
dfs(i, 0);
break;
}
printf("%d\n", ans+1); // 最后会剩下一个集合
return 0;
}

提交次数:\(0+2\)(没有处理好叶子节点)

[CF]Round510的更多相关文章

  1. ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'

    凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...

  2. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  3. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...

  4. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  5. [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

  6. CF memsql Start[c]UP 2.0 A

    CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...

  7. CF memsql Start[c]UP 2.0 B

    CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...

  8. CF #376 (Div. 2) C. dfs

    1.CF #376 (Div. 2)    C. Socks       dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...

  9. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...

随机推荐

  1. Spring学习-依赖注入

    Spring是基于IOC与AOP的框架,而其中的IOC(Inversion of Control)即反转控制是Spring的基础. 在以前学过的知识中,一个新的对象全部为自己手动new出来的,而在Sp ...

  2. VS打包程序步骤

    1.下载打包的程序 2.在你的程序里面安装打包的项目 3.添加项目输出 4.为项目添加必要的文件 双击前面建立好的主输出 一般文件为一些配置文件(如使用Nlog写日志,需要添加Nlog的配置文件)和图 ...

  3. Oracle Solaris 10 重启后提示 Bad PBR sig

    Solaris 10 安装完毕重启后提示 Bad PBR sig 在磁盘分区的时候,默认自带的 overlap 不要删除,否则启动报错. 分区时,保留overlap(默认显示总容量大小)分区.安装操作 ...

  4. 使用ResXmanager实现多语言[转]

    1 多國語系 - 使用RESXMANAGER管理資源檔 1.1 前言 在實作多國語系網站時,針對靜態文字多會使用資源檔(Resource)來對應出各語系所需顯示的內容.由於資源檔可能會依照特定結構放式 ...

  5. java学习笔记之IO编程—目录和文件的拷贝

    进行文件或目录的拷贝时,要先判断处理对象是文件还是目录,如果是文件则直接拷贝,如果是目录还需要拷贝它的子目录及其文件,这就需要递归处理了 import java.io.*; class FileUti ...

  6. linq 查询-“必须是可缩小的节点”

    出现此错误的情况 查询中先使用分组方法GroupBy()=>Select()=>OrderBy()=>ToList()(实现分组后排序) 解决方法: 排序OrderBy()应该放在S ...

  7. 利用Master库spt_values表 连续数字

    SELECT CONVERT ( ), dateadd(d, number, GETDATE()), ) AS every_time FROM master..spt_values n WHERE n ...

  8. C# asp.net 配置文件连接sql 数据库

    先引用 using System.Configuration;//配置文件using System.Data.SqlClient; 我这里使用的是SqlServer 2008  sa 用户 密码也为s ...

  9. windows redis启动

    1.下载redis 2.启动redis 3.启动redis客户端并设置protected-mode为false

  10. python3读取、写入、追加写入excel文件

    由于excel版本不同,python处理的时候选择的库页不同. 一.操作对应版本表格需要用到的库 1.操作xls格式的表格文件,需要用到的库如下: 读取:xlrd 写入:xlwt 修改(追加写入):x ...