欢迎光临
我们一直在努力

ABC448 数论分治|莫队分块构造

E题

题意非常简单,一个大到无法正常读入的N,还有一个M,需要求⌊N/M⌋\\lfloor N/M \\rfloorN/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
MNmod10007=MNmod(10007M)

首先,我们要先处理一下这个输入的游程编码,现在假设输入的是 ccc,连续出现 lll 次,假设现在已经处理完的数是$a $,那么我们要在它后面加上一段长度为 lllccc ,因此只需要让
a⋅10l+c⋅Rl(mod10007M)
a \\cdot 10^l + c \\cdot R_l \\pmod{10007M}
a10l+cRl(mod10007M)

其中
Rl=111⋯1(modP)
R_l = 111\\cdots1 \\pmod{P}
Rl=1111(modP)

至此我们已经完成很多了,接下来我们只需要求10l10^l10lRlR_lRl

如果说是偶数长l=2tl = 2tl=2t

那么RtR_tRt也就是前面 ttt 个1,后面 ttt 个1,其实也就是Rt⋅10t+RtR_t \\cdot 10^t + R_tRt10t+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=Rt10t+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=102t10R2t+1=R2t10+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 = 24025060000=240

对于每个块,将块内点按 yyy 从小到大排序:

q0,q1,…,qk−1
q_0, q_1, \\ldots, q_{k-1}
q0,q1,,qk1

其中

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(qk1)

然后扫描块,假设当前在y=cy=cy=cyyy范围为[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(qk1)

我们要从最近的端点进块,然后直接扫到另一端

如果 ∣c−L∣≤∣c−U∣|c – L| \\le |c – U|cLcU,就输出

q0,q1,…,qm−1
q_0, q_1, \\ldots, q_{m-1}
q0,q1,,qm1

否则输出

qm−1,qm−2,…,q0
q_{m-1}, q_{m-2}, \\ldots, q_0
qm1,qm2,,q0

Proof:

设坐标上界 M=2×107M = 2 \\times 10^7M=2×107

yyy 方向上:

c≤Lc \\le LcL

(L−c)+(U−L)=U−c≤M
(L – c) + (U – L) = U – c \\le M
(Lc)+(UL)=UcM

c≥Uc \\ge UcU

(c−U)+(U−L)=c−L≤M
(c – U) + (U – L) = c – L \\le M
(cU)+(UL)=cLM

L≤c≤UL \\le c \\le ULcU

min⁡(∣c−L∣,∣c−U∣)+(U−L)≤U−L≤M
\\min(|c – L|, |c – U|) + (U – L) \\le U – L \\le M
min(cL,cU)+(UL)ULM

因此 yyy 的总代价 ≤240M\\le 240M240M

最后回到起点再加 MMM,因此≤241M\\le 241M241M

241⋅2×107=4.82×109
241 \\cdot 2 \\times 10^7 = 4.82 \\times 10^9
2412×107=4.82×109

xxx 方向上:

设第 iiixxx 范围[li,ri][l_i, r_i][li,ri],记Δi=ri−li\\Delta_i = r_i – l_iΔi=rili

因为块来自按 xxx 排序后的连续区间,所以

∑Δi≤M
\\sum \\Delta_i \\le M
ΔiM

块内最多 B−1B-1B1 条边,每条边∣xi−xj∣≤Δi|x_i – x_j| \\le \\Delta_ixixjΔi

因此块内总代价

(B−1)∑Δi≤(B−1)M
(B – 1)\\sum \\Delta_i \\le (B – 1)M
(B1)Δi(B1)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)

赞(0)
未经允许不得转载:171主机测评 » ABC448 数论分治|莫队分块构造
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址