文章目录
前言
远古神题。既然被妖姬挑出来做了,而且做的并不是那么好,那就稍微总结一下。
这场比赛的A和B我全都没有想出来。
D题被卡精度然而存在整数做法。
E是赛后做的,是一道SB题,但是从这道题我知道了
1
0
5
10^5
105的数据范围也可以信仰
O
(
n
2
)
O(n^2)
O(n2)做法,只要大力卡常一定出奇迹。
倒是C因为套路所以做出来了。
思维极差,智商捉急。没有理由颓废了。
A Sereja and Contest
key
- 思维
题意
有
n
(
n
≤
2
∗
1
0
5
)
n(n \le 2*10^5)
n(n≤2∗105)个人,参数
k
k
k,每个人有一个分数
a
i
a_i
ai,还有一个
d
i
=
∑
j
=
1
j
≤
i
−
1
(
a
j
∗
(
j
−
1
)
−
(
n
−
i
)
∗
a
i
)
d_i=\sum_{j=1}^{j \le i-1}(a_j*(j-1)-(n-i)*a_i)
di=∑j=1j≤i−1(aj∗(j−1)−(n−i)∗ai)。
每次在序列中挑出
d
i
<
k
d_i<k
di<k的序号最小的那个人踢出序列,然后后面的人序号全都前移一位。重复,直到没有人的
d
i
<
k
d_i<k
di<k。
依次输出踢出的人在原序列中的序号。
思路
高妙思路。
我们观察公式,假如去掉了一个人,那么他前面的人的 d i d_i di一定增加了,所以踢出的人序号一定是递增的。这是重要性质。
然后只要从前往后扫,记录 a j ∗ ( j − 1 ) a_j*(j-1) aj∗(j−1)的前缀和,再记录去掉当前点前面所有该去掉的人后,当前点的序号,于是每个点的 d i d_i di都可以 O ( 1 ) O(1) O(1)算出来,与 k k k比较就好了。复杂度 O ( n ) O(n) O(n)。
不得不说是道好题,我不知道为什么其他人好像一眼就切掉了。我不会的都是好题
B Sereja and Periods
key
- DP
- 暴力
题意
[a, b]表示b个a串连在一起。
两个字符串 [ a , b ] [a,b] [a,b]和 [ c , d ] [c,d] [c,d],求在前者中去掉任意个字符,能变成的 [ [ c , d ] , p ] [[c,d], p] [[c,d],p]的最大的 p p p。 ( l e n ( a , c ) ≤ 100 , b , d ≤ 1 0 7 ) (len(a, c) \le 100, b,d \le 10^7) (len(a,c)≤100,b,d≤107)
思路
c n t [ i ] cnt[i] cnt[i]表示从 b b b串的 i i i位置开始匹配一个 a a a串可以匹配多少个 b b b串, n x t [ i ] nxt[i] nxt[i]表示下一次要从 b b b的哪个位置开始匹配。 O ( l e n 2 ) O(len^2) O(len2)预处理。
然后 O ( n ) O(n) O(n)暴力拿 b b b个 a a a串匹配。
代码
这题思路还是看代码比较好懂。
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int c, d, n, m, cnt[N], nxt[N];
char a[N], b[N];
bool exi[1000];
int Solve(int pos)
{
int j = 0, k = pos;
for (int i = 1; i <= n; ++ i){
if (a[i] == b[k]) ++ k;
if (k == m+1) k = 1, ++ j;
}
cnt[pos] = j;
nxt[pos] = k;
}
int Ans()
{
int j = 0, k = 1;
for (int i = 1; i <= c; ++ i){
j += cnt[k];
k = nxt[k];
}
return j;
}
int main()
{
scanf("%d%d", &c, &d);
scanf("%s%s", a+1, b+1);
n = strlen(a+1);
m = strlen(b+1);
memset(exi, 0, sizeof(exi));
for (int i = 1; i <= n; ++ i)
exi[a[i]] = 1;
for (int i = 1; i <= m; ++ i)
if (!exi[b[i]]){
puts("0");
return 0;
}
for (int i = 1; i <= m; ++ i)
Solve(i);
printf("%d\n", Ans()/d);
return 0;
}
C Sereja and Subsequences
key
- DP
- 树状数组优化
题意
有一个长度为 n n n的序列,求所有(不同的单调非减序列的各个数相乘的积)的和。
思路
非常easy,网上博客很多比如这个
D Sereja and Straight Lines
key
- 计算几何
- 二分
题意
塞雷哈在平面上放了n个点。 现在Sereja想要在平面上放置两条直线,以直角相交,使得其中一条直线与x轴以45度角相交,并且从点到直线的最大距离最小。
在这个问题中,我们考虑点 ( x 1 , y 1 ) (x1,y1) (x1,y1)和 ( x 2 , y 2 ) (x2,y2) (x2,y2)之间的距离等于 ∣ x 1 − x 2 ∣ + ∣ Y 1 − Y 2 ∣ | x1 - x2 |+| Y1 - Y2| ∣x1−x2∣+∣Y1−Y2∣。 点与直线之间的距离是从点到属于其中一条线的某个点的最小距离。
帮助Sereja,找到从点到最佳位置直线的最大距离。
思路
看这里吧tutorial。题解厉害的地方是用 ( x + y , x − y ) (x+y, x-y) (x+y,x−y)实现了旋转 45 45 45度,可以避免精度问题。
E Sereja and Squares
key
- DP
- 卡常
题意
给你一个长度 n ( n ≤ 1 0 5 ) n(n \le 10^5) n(n≤105),有一些地方已经填好括号了,求合法括号序列数。
思路
首先发现数据范围 n n n是 1 0 5 10^5 105,那么 O ( n 2 ) O(n^2) O(n2)就是 1 0 10 10^{10} 1010,假如计算机1秒大概跑 1 0 9 10^9 109次运算,那么 O ( n 2 ) O(n^2) O(n2)就有过的可能。先写出DP方程, f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i位,放了 j j j个右括号的方案数。
然后你发现这个常数还挺好卡的,首先把对于每个 i i i的 j j j的上下界卡一卡,常数瞬间小了4倍,差不多了,但是如果精益求精的话还有很多可以卡的地方。
我目前在评测速度的第一页,可以去看看哦Amorphophallus。
后记
写题解挺累的,要是什么题网上找不到题解,也不要怪谁,真的好累。