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 ...
随机推荐
- swift - UITextField 的用法
1,文本框的创建,有如下几个样式: public enum UITextBorderStyle : Int { case none 无边框 case line 直线边框 cas ...
- Python 流程控制:for
for 循环用于对一个序列进行遍历,用法如下: In [4]: for i in 'abcd': ...: print(i) ...: a b c d In [13]: for i in range( ...
- M0 M4之GPIO初始化
新唐所有的M0/M4芯片基本上所有的IO都可以发生中断,为了符合大家的习惯还是有所谓的外部中断EINT0和EINT1.有2跟GPIO脚可以配置为EINT0功能和EINT1功能,分别将发生EINT0中断 ...
- cstring、string、wstring、int、char*、tchar、 int、dword等相互转换代码输出测试
#include <string> #include <tchar.h> // _TCHAR #include <stdlib.h> #include <io ...
- JDBC--Result 获取返回集合
package jdbc.chap05; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql. ...
- LeetCode——Power of Two
Description: Given an integer, write a function to determine if it is a power of two. public class S ...
- 使用Android Studio调试内存问题
http://blog.csdn.net/yutao52shi/article/details/50055669 前言 内存问题对于Android开发者是永远的痛.如果一个android程序员说他没有 ...
- 聊聊对APM的理解
本文主要从以下几个列举对APM的认识: -什么是APM工具 -为什么要用APM工具,APM工具的价值在哪里: -什么样的APM工具适合于传统金融业: -如何用好APM工具: -精准告警 - ...
- 【Android】保存Bitmap到SD卡
1.打开读写SD卡的权限 需要在AndroidManifest.xml加入如下代码: <uses-permission android:name="android.permission ...
- Activity的LaunchMode应用场景思考
本文链接:http://blog.csdn.net/xiaodongrush/article/details/28597855 1. 有哪几种类型?分别有什么用? http://developer ...