E题
题意非常简单,一个大到无法正常读入的N,还有一个M,需要求⌊N/M⌋\\lfloor N/M \\rfloor⌊N/M⌋除以10007的余数
首先,一个非常经典的观察
⌊NM⌋ mod 10007=⌊N mod (10007M)M⌋
\\left\\lfloor \\frac{N}{M} \\right\\rfloor \\bmod 10007=
\\left\\lfloor
\\frac{N \\bmod (10007M)}{M}
\\right\\rfloor
⌊MN⌋mod10007=⌊MNmod(10007M)⌋
首先,我们要先处理一下这个输入的游程编码,现在假设输入的是 ccc,连续出现 lll 次,假设现在已经处理完的数是$a $,那么我们要在它后面加上一段长度为 lll 的 ccc ,因此只需要让
a⋅10l+c⋅Rl(mod10007M)
a \\cdot 10^l + c \\cdot R_l \\pmod{10007M}
a⋅10l+c⋅Rl(mod10007M)
其中
Rl=111⋯1(modP)
R_l = 111\\cdots1 \\pmod{P}
Rl=111⋯1(modP)
至此我们已经完成很多了,接下来我们只需要求10l10^l10l和RlR_lRl
如果说是偶数长l=2tl = 2tl=2t
那么RtR_tRt也就是前面 ttt 个1,后面 ttt 个1,其实也就是Rt⋅10t+RtR_t \\cdot 10^t + R_tRt⋅10t+Rt
而
102t=(10t)2R2t=Rt⋅10t+Rt=Rt(10t+1)
10^{2t}=(10^t)^2\\\\
R_{2t}=R_t \\cdot 10^t + R_t=R_t(10^t + 1)
102t=(10t)2R2t=Rt⋅10t+Rt=Rt(10t+1)
又如果是奇数长l=2t+1l = 2t+1l=2t+1
102t+1=102t⋅10R2t+1=R2t⋅10+1
10^{2t+1}=10^{2t} \\cdot 10\\\\
R_{2t+1}=R_{2t} \\cdot 10 + 1
102t+1=102t⋅10R2t+1=R2t⋅10+1
lll 可以在O(logl)O(log l)O(logl)内求出
总复杂度O(Klogl)O(K logl)O(Klogl)
void solve() {
int K;
ll M;
cin >> K >> M;
ll P = 10007LL * M;
function<pair<ll,ll>(ll)> calc = [&](ll len) -> pair<ll,ll> {
if (len == 1) return {10 % P, 1 % P};
if (len % 2 == 0) {
auto [A, B] = calc(len / 2);
ll A2 = A * A % P;
ll B2 = B * (A + 1) % P;
return {A2, B2};
} else {
auto [A, B] = calc(len – 1);
return {A * 10 % P, (B * 10 + 1) % P};
}
};
ll cur = 0;
for (int i = 0; i < K; i++) {
int c;
ll l;
cin >> c >> l;
auto [A, B] = calc(l);
cur = (cur * A + 1LL * c * B) % P;
}
cout << cur / M << '\\n';
}
F题
简单概括下题意,要构造一条路径,从1点出发,每个点访问一次回到1,曼哈顿距离不超过101010^{10}1010
首先先将所有点按(x,y)(x,y)(x,y)进行排序,取块的大小为B=250B=250B=250,块数最多⌊60000250⌋=240\\left\\lfloor \\frac{60000}{250} \\right\\rfloor = 240⌊25060000⌋=240
对于每个块,将块内点按 yyy 从小到大排序:
q0,q1,…,qk−1
q_0, q_1, \\ldots, q_{k-1}
q0,q1,…,qk−1
其中
y(q0)≤y(q1)≤⋯≤y(qk−1)
y(q_0) \\le y(q_1) \\le \\cdots \\le y(q_{k-1})
y(q0)≤y(q1)≤⋯≤y(qk−1)
然后扫描块,假设当前在y=cy=cy=c,yyy范围为[L,U][L,U][L,U],L=y(q0),U=y(qk−1)L=y(q_0),U=y(q_{k-1})L=y(q0),U=y(qk−1)
我们要从最近的端点进块,然后直接扫到另一端
如果 ∣c−L∣≤∣c−U∣|c – L| \\le |c – U|∣c−L∣≤∣c−U∣,就输出
q0,q1,…,qm−1
q_0, q_1, \\ldots, q_{m-1}
q0,q1,…,qm−1
否则输出
qm−1,qm−2,…,q0
q_{m-1}, q_{m-2}, \\ldots, q_0
qm−1,qm−2,…,q0
Proof:
设坐标上界 M=2×107M = 2 \\times 10^7M=2×107
在 yyy 方向上:
若c≤Lc \\le Lc≤L
则
(L−c)+(U−L)=U−c≤M
(L – c) + (U – L) = U – c \\le M
(L−c)+(U−L)=U−c≤M
若c≥Uc \\ge Uc≥U
则
(c−U)+(U−L)=c−L≤M
(c – U) + (U – L) = c – L \\le M
(c−U)+(U−L)=c−L≤M
若L≤c≤UL \\le c \\le UL≤c≤U
则
min(∣c−L∣,∣c−U∣)+(U−L)≤U−L≤M
\\min(|c – L|, |c – U|) + (U – L) \\le U – L \\le M
min(∣c−L∣,∣c−U∣)+(U−L)≤U−L≤M
因此 yyy 的总代价 ≤240M\\le 240M≤240M
最后回到起点再加 MMM,因此≤241M\\le 241M≤241M
即
241⋅2×107=4.82×109
241 \\cdot 2 \\times 10^7 = 4.82 \\times 10^9
241⋅2×107=4.82×109
在 xxx 方向上:
设第 iii 块 xxx 范围[li,ri][l_i, r_i][li,ri],记Δi=ri−li\\Delta_i = r_i – l_iΔi=ri−li
因为块来自按 xxx 排序后的连续区间,所以
∑Δi≤M
\\sum \\Delta_i \\le M
∑Δi≤M
块内最多 B−1B-1B−1 条边,每条边∣xi−xj∣≤Δi|x_i – x_j| \\le \\Delta_i∣xi−xj∣≤Δi
因此块内总代价
(B−1)∑Δi≤(B−1)M
(B – 1)\\sum \\Delta_i \\le (B – 1)M
(B−1)∑Δi≤(B−1)M
跨块跳跃和最终回边再增加最多 3M3M3M。
因此 xxx 的总代价 ≤(B+2)M\\le (B + 2)M≤(B+2)M
取 B=250B = 250B=250
252M=5.04×109
252M = 5.04 \\times 10^9
252M=5.04×109
总距离
5.04×109+4.82×109=9.86×109<1010
5.04 \\times 10^9 + 4.82 \\times 10^9 = 9.86 \\times 10^9 < 10^{10}
5.04×109+4.82×109=9.86×109<1010
总时间复杂度:O(NlogN)O(NlogN)O(NlogN)


