Educational Codeforces Round 57 Solution
A. Find Divisible
签到。
#include <bits/stdc++.h>
using namespace std; int t, l, r; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &l, &r);
printf("%d %d\n", l, l * );
}
return ;
}
B. Substring Removal
签到。
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 200010
const ll MOD = ;
int len;
char s[N]; ll f(ll x) { return x * (x + ) / ; } int main()
{
while (scanf("%d", &len) != EOF)
{
scanf("%s", s + );
int l, r;
for (l = ; l <= len; ++l) if (s[l] != s[l - ])
break;
for (r = len - ; r >= ; --r) if (s[r] != s[r + ])
break;
ll res;
r = len - r + ;
if (s[] == s[len])
res = min(f(len), 1ll * l * r);
else
res = min(f(len), 1ll * l + r - );
printf("%lld\n", res % MOD);
}
return ;
}
C. Polygon for the Angle
Solved.
题意:
问在一个正n多边形中任意三点构成的角的集合中包含ang的最小的n是多少
思路:
一个正$n多边形每个角的大小是 x = 180 - \frac{360}{n}$
我们考虑点可以怎么选,如果中间的点固定,两边的点往两边走的话
我们可以发现单侧的一条边和单侧会构成一个多边形
这个多边形有$k个角,但是有k - 2个角都是x,并且剩下的两个角相等$
这样就可以算出选的点往两边扩展会减去的角的大小
我们发现,两个点往两边扩展分别构成的多边形的点数为$k, o$
那么 $k + o <= n + 1$
那么通过整理我们发现一个多边形可以构成的角的集合为
$180 - (180 - (j - 2)) / n \;\; j \in [4, n + 1]$
而且我们发现 当$n = 180 的时候可以构成[1, 179]种的任意角,那么遍历一下,遍历到180预处理一下答案即可$
#include <bits/stdc++.h>
using namespace std; int t, n;
int ans[]; int main()
{
memset(ans, -, sizeof ans);
for (int i = ; i >= ; --i) for (int j = ; j <= i + ; ++j) if (( * (j - ) % i) == )
{
int x = - ( * (j - )) / i;
ans[x] = i;
}
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
printf("%d\n", ans[n]);
}
return ;
}
D. Easy Problem
Upsolved.
题意:
给处一个字符串,有权,求移除一些字符使得花费最少并且没有一个子序列构成'hard'
思路:
我们发现只要断掉一种字符的路就可以了
那么对于'h' 要断掉它的路就必然要去掉所有的'h'
但是对于'a', 'r', 'd' 这三种字符来说,断掉他们的路,可以选择去掉当前
遇到的字符,或者去掉前面所有在他们前面位置的那个字符
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
int n; ll dp[N];
char s[N]; int main()
{
while (scanf("%d", &n) != EOF)
{
scanf("%s", s + );
memset(dp, 0x3f, sizeof dp);
dp[] = ;
for (int i = , a; i <= n; ++i)
{
scanf("%d", &a);
if (s[i] == 'h')
{
dp[] = min(dp[], dp[]);
dp[] += a;
}
else if (s[i] == 'a')
{
dp[] = min(dp[], dp[]);
dp[] += a;
}
else if (s[i] == 'r')
{
dp[] = min(dp[], dp[]);
dp[] += a;
}
else if (s[i] == 'd')
dp[] += a;
}
printf("%lld\n", *min_element(dp, dp + ));
}
return ;
}
F. Inversion Expectation
UpSolved.
题意:
有一个排列,有些位置空着,求逆序对的期望
思路:
约定没有确定的数的个数为$x$
对于确定的数,它的贡献由两部分构成
1° 它对其他确定的数的贡献
2° 它对不确定的数的贡献
第一部分 我们可以对确定的数做一遍逆序对,然后乘$fac[x] 即可$
第二部分 我们可以算不确定的数对它的贡献
那么对于不确定的数
1° 它可以在任意的空位上,并且在每个空位上的可能次数为$fac[x - 1]$,
那么在一个空位上的单次贡献是在它前面的比它大的数的个数和在它后面的比它小的个数
这个将不确定的数排序,从小到大做一遍,再从大到小做一遍,我们发现贡献是递增的
每个确定的数只会拿出来做一次
2° 那么对于不确定的数,我们知道,不确定的数可以在任意个空位,
比它大的数如果在它之前的任意空位上就会产生贡献
那么考虑,一个比他大的数在它前面的某个位置,这个时候这两个数的位置确定
剩下的数的排列种树为$fac[x - 2]$
并且比他大的数可以在他前面的任意一个空位
即空位数 * 比它大的数 * fac[x - 2] 就是一个不确定的数产生的贡献
#include <bits/stdc++.h>
using namespace std; #define N 200010
#define ll long long
const ll MOD = ;
int n, a[N], b[N], pos[N], sum[N][]; ll qmod(ll base, ll n)
{
ll res = ;
while (n)
{
if (n & ) res = (res * base) % MOD;
base = (base * base) % MOD;
n >>= ;
}
return res;
} ll fac[N];
void init()
{
fac[] = ;
for (int i = ; i <= ; ++i) fac[i] = (fac[i - ] * i) % MOD;
} ll f(ll x)
{
return x * (x + ) / ;
} struct BIT
{
int a[N];
void init() { memset(a, , sizeof a); }
void update(int x)
{
for (; x <= n; x += x & -x)
++a[x];
}
int query(int x)
{
int res = ;
for (; x; x -= x & -x)
res += a[x];
return res;
}
}bit; int main()
{
init();
while (scanf("%d", &n) != EOF)
{
memset(pos, -, sizeof pos);
bit.init();
for (int i = ; i <= n; ++i) scanf("%d", a + i);
for (int i = ; i <= n; ++i) if (a[i] != -)
pos[a[i]] = i;
sum[n + ][] = ;
ll tot[] = {, };
for (int i = n; i >= ; --i)
sum[i][] = sum[i + ][] + (a[i] == -);
for (int i = ; i <= n; ++i) if (a[i] != -)
tot[] += sum[i][];
sum[][] = ;
for (int i = ; i <= n; ++i)
sum[i][] = sum[i - ][] + (a[i] == -);
for (int i = ; i <= n; ++i) if (a[i] != -)
tot[] += sum[i][];
b[] = ;
for (int i = ; i <= n; ++i) if (pos[i] == -)
b[++b[]] = i;
ll res = ;
int down = , up = n;
for (int i = ; i <= b[]; ++i)
{
while (down < b[i])
{
if (pos[down] != -) tot[] -= sum[pos[down]][];
++down;
}
res = (res + fac[b[] - ] * (f(b[] - ) % MOD) % MOD * (b[] - i) % MOD) % MOD;
res = (res + tot[] % MOD * fac[b[] - ] % MOD) % MOD;
}
for (int i = b[]; i >= ; --i)
{
while (up > b[i])
{
if (pos[up] != -) tot[] -= sum[pos[up]][];
--up;
}
res = (res + tot[] % MOD * fac[b[] - ] % MOD) % MOD;
}
ll tmp = ;
for (int i = ; i <= n; ++i) if (a[i] != -)
{
bit.update(a[i]);
tmp += bit.query(n) - bit.query(a[i]);
}
res = (res + tmp * fac[b[]] % MOD) % MOD;
printf("%lld\n", res * qmod(fac[b[]], MOD - ) % MOD);
}
return ;
}
Educational Codeforces Round 57 Solution的更多相关文章
- Educational Codeforces Round 57 (Rated for Div. 2) ABCDEF题解
题目总链接:https://codeforces.com/contest/1096 A. Find Divisible 题意: 给出l,r,在[l,r]里面找两个数x,y,使得y%x==0,保证有解. ...
- Educational Codeforces Round 57 (Rated for Div. 2) D dp
https://codeforces.com/contest/1096/problem/D 题意 给一个串s,删掉一个字符的代价为a[i],问使得s的子串不含"hard"的最小代价 ...
- Educational Codeforces Round 57 (Rated for Div. 2) C 正多边形 + 枚举
https://codeforces.com/contest/1096/problem/C 题意 问是否存在一正多边形内三点构成的角度数为ang,若存在输出最小边数 题解 三点构成的角是个圆周角,假设 ...
- CF Educational Codeforces Round 57划水记
因为是unrated于是就叫划水记了,而且本场也就用了1h左右. A.B:划水去了,没做 C:大水题,根据初三课本中圆的知识,可以把角度化成弧长,而这是正多边形,所以又可以化成边数,于是假设读入为a, ...
- Codeforces Educational Codeforces Round 57 题解
传送门 Div 2的比赛,前四题还有那么多人过,应该是SB题,就不讲了. 这场比赛一堆计数题,很舒服.(虽然我没打) E. The Top Scorer 其实这题也不难,不知道为什么这么少人过. 考虑 ...
- Educational Codeforces Round 57 (Rated for Div. 2)
我好菜啊. A - Find Divisible 好像没什么可说的. #include<cstdio> #include<cstring> #include<algori ...
- Educational Codeforces Round 57题解
A.Find Divisible 沙比题 显然l和2*l可以直接满足条件. 代码 #include<iostream> #include<cctype> #include< ...
- Educational Codeforces Round 56 Solution
A. Dice Rolling 签到. #include <bits/stdc++.h> using namespace std; int t, n; int main() { scanf ...
- Educational Codeforces Round 58 Solution
A. Minimum Integer 签到. #include <bits/stdc++.h> using namespace std; #define ll long long ll l ...
随机推荐
- Java架构学习 转(Spring+SpringMVC+MyBatis+easyUI)
Spring+SpringMVC+MyBatis+easyUI : http://www.cnblogs.com/han-1034683568/p/6730869.html
- python2.0_day22_web聊天室二
上节内容已经实现了客户端使用长轮询的方式获取消息的功能.但是还没有展现到前端.本节内容将实现1.展现消息到前端窗口.2.客户端之间发送图片和文件.3.文件上传时显示进度条 下面我们来实现上面3个功能. ...
- linux 统计命令执行后的行数或者统计目录下文件数目
ls |wc 是统计你这个目录下的文件数目.ls |wc -l是输出第一个结果即31即文件的数目.
- complex()
complex() 用于将一个对象转换为复数 In [1]: complex(123) # 将整数转换为复数 Out[1]: (123+0j) In [2]: complex(') # 将纯数字的字符 ...
- Android中Parcelable和Serializable接口用法
1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel. ...
- mac 特殊符号的操作
——快捷键符号对照表,Mac下的那些符号都代表哪些按键? 这期我们教大家认识符号. 在Mac的快捷键中经常会有一些符号,比如⌘.⌥.⇧.⌃等,而Mac下只有command键上有一个⌘的符号,而其他按键 ...
- 使用OpenRowSet操作Excel Excel导入数据库
使用 OpenRowSet 和 OpenDataSource 访问 Excel 97-2007 测试文件:D:\97-2003.xls和D:\2007.xlsx,两个文件的内容是一模一样的. 测试环境 ...
- 【BZOJ3275】Number 最小割
[BZOJ3275]Number Description 有N个正整数,需要从中选出一些数,使这些数的和最大.若两个数a,b同时满足以下条件,则a,b不能同时被选1:存在正整数C,使a*a+b*b=c ...
- thinkphp --- 写入日志
在开发过程中,对于一些参数,不好直接输入或者打印调试,特别是在微信开发过程中,这个时候,通过日志来查看信息就显得格外重要. 下面是在TP3.2.3框架中,写入日志的方法: public functio ...
- jps命令用法
jps是jdk提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写.非常简单实用. 命令格式:jps [option ...