Codeforces 451 Div2

其实451和452两场就真的挺简单的了,但就是脑残了。

写一下补的题目吧。其余的题目都很水了。

D题贪心,从左到右扫,不满足的时候就把最右边的删掉就好了。我居然写了个树状数组。。。(脑残。。。然后判断的时候一种情况没考虑到就WA掉了。。。

E题就直接分情况讨论就好了,把多于n/2的那部分贪心移过去。

F题可以说一下哈。给定一个字符串,要写成X+Y=Z的形式。字符串长度$10^6$级别。

首先肯定是枚举第一个数的分隔的位置。。。然后,我就不知道怎么做了。。。

X+Y=Z这种,Z的长度要么和X相同,要么比X多1,要么和Y相同,要么比Y多1。就这四种情况啊。这样就完了啊。

然后怎么判断加法呢,前缀和哈希一下,这里我还是trick,运气好了过去了。比赛里面还是要写两个hash check的。。(当初惨痛的教训。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
int len;
char val[maxn];
ll inv[maxn], pre[maxn], f[maxn];

bool check(int st, int en)
{

int len1 = st;
int len2 = en - st;
int len3 = len - en;
if (len1 > len3 || len2 > len3)return false;
if (len1 <= 0 || len2 <= 0 || len3 <= 0)return false;

if (len1>1 && val[1] == '0')return false;
if (len2>1 && val[st + 1] == '0')return false;
if (len3>1 && val[en + 1] == '0')return false;

ll sum1 = pre[st];
ll sum2 = (pre[en] - pre[st] * f[en - st] % mod) % mod;
sum2 = (sum2%mod + mod) % mod;
ll sum3 = (pre[len] - pre[en] * f[len - en] % mod) % mod;
sum3 = (sum3%mod + mod) % mod;
if ((sum1 + sum2)%mod != sum3)return false;
for (int i = 1; i <= len; i++)
{
printf("%c", val[i]);
if (i == st)printf("+");
if (i == en)printf("=");
}
return true;
}

void solve()
{
scanf("%s", val + 1);
len = strlen(val + 1);
inv[0] = 1;
f[0] = 1;
int up = 1e6;
repp(i, 1, up)
{
f[i] = f[i-1] * 10 % mod;
}
repp(i, 1, len)
{
pre[i] = pre[i - 1] * 10 + val[i] - '0';
pre[i] %= mod;
}

repp(i, 1, len)
{
if (check(i, len - i))
{
return;
}
if (check(i, len - i - 1))
{
return;
}
if (check(len - i - i, len - i))
{
return;
}
if (check(len - i - i - 1, len - i - 1))
{
return;
}
}
}