CF1043
找个下午打了场CF,结果被某uranus吊打......一千多名,过弱。
T1,一眼二分了,后来发现题解是O(1)的hhh
T2,题意精炼一下就是让你找一个串的循环节个数,直接n²枚举.....
T3,给你一个ab串,你依次考虑每个前缀,选择reverse这个前缀或者不操作。输出方案使得最后的字典序最小。
手玩一下就能发现,一定能构造出最小字典序,所有a都在b前面。
具体操作是每个整段的结尾字符那里翻转。
T4,给你10个1e5的排列,你需要从每个中提取连续的一段,使得这十段相同。求方案数。
考虑KMP(????),就是我们线性的扫描第一个串,把它分成若干段十个串都相同的段,这样每段都可以拿公式计算。
第一次交的时候一个中间变量没开long long挂了,太SB了。
T5,题意有点长......就是给你n个人,你要把这n个人两两组队(就是n(n-1)/2次)各一次,每次解决两个任务a,b。
每个人解决a,b问题都有个代价。组队时一人解决一道题,会自动选择总代价最小的解决方案,代价累加到两个人身上。
问你这么多次下来每个人的总代价。
把式子min(A + b, B + a)变形一下:min(b - a, B - A) + a + A
然后就比较显然了.....显然可以用前缀和但是我SB的用了树状数组,不过复杂度一样。
贴个考场代码吧。
#include <bits/stdc++.h>
inline void read(int &x) {
x = ;
char c = getchar();
while(c < '' || c > '') {
c = getchar();
}
while(c >= '' && c <= '') {
x = (x << ) + (x << ) + c - ;
c = getchar();
}
return;
}
typedef long long LL;
const int N = ;
LL xi[N], yi[N], dt[N], X[N], ans[N];
int n, pos[N];
struct TA {
LL ta[N];
inline void add(int i, LL v) {
for(; i <= n; i += i & (-i)) {
ta[i] += v;
}
return;
}
inline LL getsum(int i) {
LL ans = ;
for(; i > ; i -= i & (-i)) {
ans += ta[i];
}
return ans;
}
inline LL ask(int l, int r) {
if(r < l) {
return ;
}
if(l <= ) {
return getsum(r);
}
return getsum(r) - getsum(l - );
}
}cnt, sum;
int main() {
int m;
scanf("%d%d", &n, &m);
LL tot = ;
for(int i = ; i <= n; i++) {
scanf("%lld%lld", &xi[i], &yi[i]);
dt[i] = yi[i] - xi[i];
X[i] = dt[i];
tot += xi[i];
}
std::sort(X + , X + n + );
int xx = std::unique(X + , X + n + ) - X - ;
for(int i = ; i <= n; i++) {
int p = std::lower_bound(X + , X + xx + , dt[i]) - X;
pos[i] = p;
cnt.add(p, );
sum.add(p, dt[i]);
}
for(int i = ; i <= n; i++) {
int p = pos[i];
ans[i] += sum.ask(, p) - dt[i];
ans[i] += cnt.ask(p + , n) * dt[i];
ans[i] += tot - xi[i] + xi[i] * (n - );
}
for(int i = , x, y; i <= m; i++) {
scanf("%d%d", &x, &y);
ans[x] -= std::min(xi[x] + yi[y], xi[y] + yi[x]);
ans[y] -= std::min(xi[x] + yi[y], xi[y] + yi[x]);
}
for(int i = ; i <= n; i++) {
printf("%lld ", ans[i]);
}
return ;
}
AC代码
当时境况比较尴尬,写出来时发现比赛刚结束68s......
第一次交很SB的把long long用%d输出了。
最后1104名......F题听说很有趣,以后来填。
F 题意:给定n个数,从中选出尽量少的数,使得gcd为1。
不存在方案输出-1。n,值域<=300000。
解:正解是:有个结论,如果存在合法解,那么一定有一组合法解的个数不超过7。不会证...
然后设f[i][j]表示选i个数,gcd为j的方案数。
f[i][j] = C(sumj, i) - ∑f[i][j * d]
然后求出一个最小的i使得f[i][1] > 0即可。
#include <cstdio>
#include <algorithm> typedef long long LL;
const int N = , lm = ;
const LL mo[] = {, (LL)(1e9 + )}; int sum[N], bin[N], n;
LL f[][N], nn[N], invn[N], inv[N], MO; inline LL C(int n, int i) {
return nn[n] * invn[i] % MO * invn[n - i] % MO;
} inline int cal(int turn) {
MO = mo[turn];
for(int i = ; i <= lm; i++) {
nn[i] = nn[i - ] * i % MO;
inv[i] = (MO - inv[MO % i]) * (MO / i) % MO;
invn[i] = invn[i - ] * inv[i] % MO;
}
for(int i = ; i <= ; i++) {
for(int j = lm; j >= ; j--) {
if(sum[j] < i) {
continue;
}
f[i][j] = C(sum[j], i);
for(int k = ; k * j <= lm; k++) {
f[i][j] = (f[i][j] - f[i][j * k] + MO) % MO;
}
//printf("f %d %d = %d \n", i, j, f[i][j]);
}
}
for(int i = ; i <= ; i++) {
if(f[i][]) {
return i;
}
}
return -;
} int main() {
nn[] = inv[] = invn[] = ;
nn[] = inv[] = invn[] = ;
int n;
scanf("%d", &n);
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
bin[x]++;
}
for(int i = ; i <= lm; i++) {
for(int j = ; j * i <= lm; j++) {
sum[i] += bin[i * j];
}
} int a = cal(), b = cal();
int ans = std::min(a, b);
if(ans == -) {
printf("%d", std::max(a, b));
}
else {
printf("%d", std::min(a, b));
}
return ;
}
AC代码
反演+二分解法:
首先二分答案,然后用反演求:选出k个,gcd为1的方案数。如果大于0就可行。
#include <bits/stdc++.h> const int N = , MO = ; int p[N], top, miu[N], bin[N], fac[N], inv[N], invn[N];
bool vis[N]; inline int C(int n, int m) {
if(m > n || n < || m < ) return ;
return 1ll * fac[n] * invn[m] % MO * invn[n - m] % MO;
} inline void getp(int n) {
miu[] = ;
for(int i = ; i <= n; i++) {
if(!vis[i]) {
p[++top] = i;
miu[i] = -;
}
for(int j = ; j <= top && i * p[j] <= n; j++) {
vis[i * p[j]] = ;
if(i % p[j] == ) {
miu[i * p[j]] = ;
break;
}
miu[i * p[j]] = -miu[i];
}
}
return;
} inline int check(int k) {
int ans = ;
for(int i = ; i < N; i++) {
(ans += miu[i] * C(bin[i], k)) %= MO;
ans = (ans + MO) % MO;
}
return ans;
} int main() {
getp(N - );
inv[] = fac[] = invn[] = ;
inv[] = fac[] = invn[] = ;
for(int i = ; i < N; i++) {
fac[i] = 1ll * fac[i - ] * i % MO;
inv[i] = 1ll * inv[MO % i] * (MO - MO / i) % MO;
invn[i] = 1ll * invn[i - ] * inv[i] % MO;
}
int n;
scanf("%d", &n);
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
bin[x]++;
}
for(int i = ; i < N; i++) {
for(int j = i << ; j < N; j += i) {
(bin[i] += bin[j]) %= MO;
}
} int l = , r = n + ;
while(l < r) {
int mid = (l + r) >> ;
if(check(mid)) {
r = mid;
}
else {
l = mid + ;
}
}
if(r == n + ) printf("-1\n");
else printf("%d\n", r);
return ;
}
AC代码
CF1043的更多相关文章
随机推荐
- EXPERT FOR SQL SERVER诊断系列--索引
概述 索引设计是数据库设计中比较重要的一个环节,对数据库的性能起着至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其 ...
- 从0到1上线一个微信小程序
0.0 前期准备 微信小程序的出现极大地降低了个人开发者微创业的门槛,不需要后端技术,不需要服务器和域名这些乱七八糟的前置操作,只需要懂得前端技术,就能发布一款属于自己的轻量级应用,简直是前端开发者的 ...
- open-falcon ---客户机agent操作
open-falcon的agent用于采集机器负载监控指标,比如cpu.idle.load.1min.disk.io.util等等,每隔60秒push给Transfer.agent与Transfer建 ...
- 个人博客week7
IBM大型机之父佛瑞德·布鲁克斯(Frederick P. Brooks, Jr.)在1986年发表的一篇关于软件工程的经典论文,便以<没有银弹:软件工程的本质性与附属性工作>(No Si ...
- “Linux内核分析”第五周报告
张文俊+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 学习总结 1.给M ...
- 《Linux内核设计与实现》读书笔记 3
第三章 进程管理 3.1进程 概念: 进程:处于执行期的程序.但不仅局限于程序,还包含其他资源(打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内催音社的内存地址空间及一个或多个执行线 ...
- 《Linux内核分析》读书笔记(四章)
<Linux内核分析>读书笔记(四章) 标签(空格分隔): 20135328陈都 第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间,进程调度程序可看做在可运行 ...
- SqlDataAdapter简单介绍 (转)
From: http://blog.sobnb.com/u/92/5532.html 一.特点介绍 1.表示用于填充 DataSet 和更新 SQL Server 数据库的一组数据命令和一个数据库连 ...
- /var/lib/mysql 的访问权限问题 Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
mysql 登录不进去 提示Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) she ...
- 小学四则运算APP 第三阶段冲刺-第一天
团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第三次冲刺阶段时间:12.12~12.19 本次发布的是音乐播放功能,可以根据用户需求一边播放音乐一边做题,也拥有暂停播放音乐的功能,增强 ...