Educational Codeforces Round 57 Solution

A. Find Divisible

签到。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int t, l, r;
 5
 6 int main()
 7 {
 8     scanf("%d", &t);
 9     while (t--)
10     {
11         scanf("%d%d", &l, &r);
12         printf("%d %d\n", l, l * 2);
13     }
14     return 0;
15 }

B. Substring Removal

签到。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define ll long long
 5 #define N 200010
 6 const ll MOD = 998244353;
 7 int len;
 8 char s[N];
 9
10 ll f(ll x) { return x * (x + 1) / 2; }
11
12 int main()
13 {
14     while (scanf("%d", &len) != EOF)
15     {
16         scanf("%s", s + 1);
17         int l, r;
18         for (l = 2; l <= len; ++l) if (s[l] != s[l - 1])
19             break;
20         for (r = len - 1; r >= 1; --r) if (s[r] != s[r + 1])
21             break;
22         ll res;
23         r = len - r + 1;
24         if (s[1] == s[len])
25             res = min(f(len), 1ll * l * r);
26         else
27             res = min(f(len), 1ll * l + r - 1);
28         printf("%lld\n", res % MOD);
29     }
30     return 0;
31 }

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预处理一下答案即可$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int t, n;
 5 int ans[200];
 6
 7 int main()
 8 {
 9     memset(ans, -1, sizeof ans);
10     for (int i = 360; i >= 1; --i) for (int j = 4; j <= i + 1; ++j) if ((180 * (j - 2) % i) == 0)
11     {
12         int x = 180 - (180 * (j - 2)) / i;
13         ans[x] = i;
14     }
15     scanf("%d", &t);
16     while (t--)
17     {
18         scanf("%d", &n);
19         printf("%d\n", ans[n]);
20     }
21     return 0;
22 }

D. Easy Problem

Unsolevd.

题意:

给处一个字符串,有权,求移除一些字符使得花费最少并且没有一个子序列构成‘hard‘

F. Inversion Expectation

UpSolved.

题意:

有一个排列,有些位置空着,求逆序对的期望

思路:

约定没有确定的数的个数为$x$

对于确定的数,它的贡献由两部分构成

1° 它对其他确定的数的贡献

2° 它对不确定的数的贡献

第一部分 我们可以对确定的数做一遍逆序对,然后乘$fac[x] 即可$

第二部分 我们可以算不确定的数对它的贡献

那么对于不确定的数

1° 它可以在任意的空位上,并且在每个空位上的可能次数为$fac[x - 1]$,

那么在一个空位上的单次贡献是在它前面的比它大的数的个数和在它后面的比它小的个数

这个将不确定的数排序,从小到大做一遍,再从大到小做一遍,我们发现贡献是递增的

每个确定的数只会拿出来做一次

2° 那么对于不确定的数,我们知道,不确定的数可以在任意个空位,

比它大的数如果在它之前的任意空位上就会产生贡献

那么考虑,一个比他大的数在它前面的某个位置,这个时候这两个数的位置确定

剩下的数的排列种树为$fac[x - 2]$

并且比他大的数可以在他前面的任意一个空位

即空位数 * 比它大的数 * fac[x - 2] 就是一个不确定的数产生的贡献

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define N 200010
  5 #define ll long long
  6 const ll MOD = 998244353;
  7 int n, a[N], b[N], pos[N], sum[N][2];
  8
  9 ll qmod(ll base, ll n)
 10 {
 11     ll res = 1;
 12     while (n)
 13     {
 14         if (n & 1) res = (res * base) % MOD;
 15         base = (base * base) % MOD;
 16         n >>= 1;
 17     }
 18     return res;
 19 }
 20
 21 ll fac[N];
 22 void init()
 23 {
 24     fac[0] = 1;
 25     for (int i = 1; i <= 200000; ++i) fac[i] = (fac[i - 1] * i) % MOD;
 26 }
 27
 28 ll f(ll x)
 29 {
 30     return x * (x + 1) / 2;
 31 }
 32
 33 struct BIT
 34 {
 35     int a[N];
 36     void init() { memset(a, 0, sizeof a); }
 37     void update(int x)
 38     {
 39         for (; x <= n; x += x & -x)
 40             ++a[x];
 41     }
 42     int query(int x)
 43     {
 44         int res = 0;
 45         for (; x; x -= x & -x)
 46             res += a[x];
 47         return res;
 48     }
 49 }bit;
 50
 51 int main()
 52 {
 53     init();
 54     while (scanf("%d", &n) != EOF)
 55     {
 56         memset(pos, -1, sizeof pos);
 57         bit.init();
 58         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
 59         for (int i = 1; i <= n; ++i) if (a[i] != -1)
 60             pos[a[i]] = i;
 61         sum[n + 1][0] = 0;
 62         ll tot[2] = {0, 0};
 63         for (int i = n; i >= 1; --i)
 64             sum[i][0] = sum[i + 1][0] + (a[i] == -1);
 65         for (int i = 1; i <= n; ++i) if (a[i] != -1)
 66             tot[0] += sum[i][0];
 67         sum[0][1] = 0;
 68         for (int i = 1; i <= n; ++i)
 69             sum[i][1] = sum[i - 1][1] + (a[i] == -1);
 70         for (int i = 1; i <= n; ++i) if (a[i] != -1)
 71             tot[1] += sum[i][1];
 72         b[0] = 0;
 73         for (int i = 1; i <= n; ++i) if (pos[i] == -1)
 74             b[++b[0]] = i;
 75         ll res = 0;
 76         int down = 1, up = n;
 77         for (int i = 1; i <= b[0]; ++i)
 78         {
 79             while (down < b[i])
 80             {
 81                 if (pos[down] != -1) tot[0] -= sum[pos[down]][0];
 82                 ++down;
 83             }
 84             res = (res + fac[b[0] - 2] * (f(b[0] - 1) % MOD) % MOD * (b[0] - i) % MOD) % MOD;
 85             res = (res + tot[0] % MOD * fac[b[0] - 1] % MOD) % MOD;
 86         }
 87         for (int i = b[0]; i >= 1; --i)
 88         {
 89             while (up  > b[i])
 90             {
 91                 if (pos[up] != -1) tot[1] -= sum[pos[up]][1];
 92                 --up;
 93             }
 94             res = (res + tot[1] % MOD * fac[b[0] - 1] % MOD) % MOD;
 95         }
 96         ll tmp = 0;
 97         for (int i = 1; i <= n; ++i) if (a[i] != -1)
 98         {
 99             bit.update(a[i]);
100             tmp += bit.query(n) - bit.query(a[i]);
101         }
102         res = (res + tmp * fac[b[0]] % MOD) % MOD;
103         printf("%lld\n", res * qmod(fac[b[0]], MOD - 2) % MOD);
104     }
105     return 0;
106 }

原文地址:https://www.cnblogs.com/Dup4/p/10193658.html

时间: 2024-10-08 14:26:49

Educational Codeforces Round 57 Solution的相关文章

Educational Codeforces Round 57 (Rated for Div. 2)

get人生第二场CF! 成绩:(exACM) rank858 AC3/7 Penalty57 rating1648(+52) 题目:Educational Codeforces Round 57 (Rated for Div. 2) 错题题解: D. Easy Problem E. The Top Scorer F. Inversion Expectation G. Lucky Tickets 原文地址:https://www.cnblogs.com/xht37/p/10198321.html

Educational Codeforces Round 59 Solution

A. Digits Sequence Dividing 签. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 char s[N]; int n; 6 7 void solve() 8 { 9 if (n == 2 && s[1] >= s[2]) 10 { 11 puts("NO"); 12 return; 13 } 14 else 15 { 16 puts(

CF Educational Codeforces Round 57划水记

因为是unrated于是就叫划水记了,而且本场也就用了1h左右. A.B:划水去了,没做 C:大水题,根据初三课本中圆的知识,可以把角度化成弧长,而这是正多边形,所以又可以化成边数,于是假设读入为a,就是周长的a/180,gcd一下就行了,注意如果a/b这个分数满足a+1=b,那么就要ans*=2 #include<bits/stdc++.h> using namespace std; int main() { int T;scanf("%d",&T); while

Educational Codeforces Round 57 (Rated for Div. 2) ABCDF题解

ZZ出题人写NTT写成ZZ了吧,全是998244353,不需要取模的东西强行取模搞得我以为答案很大想了好久(指B题) A.任意输出 \([l,r]\) 内的一组满足 \(x \mid y\) 的 \(x, y\) ,保证有答案 我输出了 \(\lfloor \frac{r}{l} \rfloor \times l\) 输出2l也行 int main() { int T; in, T; while (T--) { int l, r; in, l, r; out, l, ' ', r / l * l

Educational Codeforces Round 57 (Rated for Div. 2) 前三个题补题

感慨 最终就做出来一个题,第二题差一点公式想错了,又是一波掉分,不过我相信我一定能爬上去的 A Find Divisible(思维) 上来就T了,后来直接想到了题解的O(1)解法,直接输出左边界和左边界*2即可 代码 #include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); long long x,y,t; cin>>t;

Codeforces Educational Codeforces Round 57 题解

传送门 Div 2的比赛,前四题还有那么多人过,应该是SB题,就不讲了. 这场比赛一堆计数题,很舒服.(虽然我没打) E. The Top Scorer 其实这题也不难,不知道为什么这么少人过. 考虑枚举那人的分数和有多少人和他同分,推一下就会发现我们只需要知道\(calc(sum,n,top)\)表示\(sum\)分,分给\(n\)个人,分数小于\(top\),的方案数. 好像不是很好直接搞,考虑容斥,枚举一下至少有几个人不满足条件即可. #include<bits/stdc++.h> na

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Educational Codeforces Round 23 F. MEX Queries(线段树)

题目链接:Educational Codeforces Round 23 F. MEX Queries 题意: 一共有n个操作. 1.  将[l,r]区间的数标记为1. 2.  将[l,r]区间的数标记为0. 3.  将[l,r]区间取反. 对每个操作,输出标记为0的最小正整数. 题解: hash后,用线段树xjb标记一下就行了. 1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<&l

Educational Codeforces Round 21 F. Card Game(网络流之最大点权独立集)

题目链接:Educational Codeforces Round 21 F. Card Game 题意: 有n个卡片,每个卡片有三个值:p,c,l; 现在让你找一个最小的L,使得满足选出来的卡片l<=L,并且所有卡片的p的和不小于k. 选择卡片时有限制,任意两张卡片的c之和不能为质数. 题解: 和hdu 1565 方格取数(2)一样,都是求最大点权独立集. 不难看出来,这题再多一个二分. 注意的是在构造二部图的时候,按照c值的奇偶性构造. 当c==1时要单独处理,因为如果有多个c==1的卡片,