Codechef September Challenge 2019 Division 1 题解

大一滚来打ACM了…

Chef Designed a Network

首先排除 n = 1 n=1 n=1 和无解的情况,然后二分答案 d d d
d = 2 d=2 d=2 时,显然最多能连的边为 n + 1 n+1 n+1
显然在 d ≥ 3 d\geq 3 d3 时所有点上一定都有自环,因为自环一定比从这个点连出去的另一条优。然后打表可以发现连完边后剩下的度数和一定是 1 1 1 0 0 0 。那么总共最多能连的边就是 ⌊ n ⋅ ( d + 1 ) 2 ⌋ \lfloor{ n\cdot (d+1) \over 2 }\rfloor 2n(d+1)

代码

Fuzzy Linear Combinations

由裴蜀定理得, x 1 , x 2 , … , x n x_1,x_2,\dots,x_n x1,x2,,xn 的所有线性组合就是 gcd ⁡ ( x 1 , x 2 , … , x n ) \gcd(x_1,x_2,\dots,x_n) gcd(x1,x2,,xn) 的所有倍数。
那么只需要对 [ 1 , max ⁡ k ] [1,\max_k] [1,maxk] 中所有数求出 gcd ⁡ \gcd gcd 等于它的区间个数,询问的时候求出 k k k 的所有因数就可以了。
统计每个区间 gcd ⁡ \gcd gcd 可以从右往左枚举左端点,那么 gcd ⁡ \gcd gcd 出现变化的右端点只有 O ( log ⁡ max ⁡ A i ) O(\log \max_{A_i}) O(logmaxAi) 个,维护这些右端点就好啦。
时间复杂度 O ( N log ⁡ A i + Q K ) O(N\log A_i+Q\sqrt K) O(NlogAi+QK )

代码

Biladerim Icin

可以发现就是统计 b 2 ≤ a c , a ∈ [ 1 , A − 1 ] , b ∈ [ 1 , B ] , c ∈ [ 1 , C − 1 ] b^2\leq ac,a\in [1,A-1],b\in [1,B],c\in [1,C-1] b2ac,a[1,A1],b[1,B],c[1,C1]
不妨设 A < C A<C A<C
把式子化成 c > b 2 a c>{{b^2}\over a} c>ab2 ,这样答案就是
∑ b = 1 B ∑ a = ⌈ b 2 C ⌉ min ⁡ { A − 1 , b 2 } C − 1 − ⌊ b 2 a ⌋ \sum_{b=1}^B\sum_{a=\lceil{b^2\over C}\rceil}^{\min\{A-1,b^2\}}C-1-\lfloor{b^2\over a}\rfloor b=1Ba=Cb2min{A1,b2}C1ab2
s t = ⌈ b 2 C ⌉ , e d = min ⁡ { A − 1 , b 2 } st=\lceil{b^2\over C}\rceil,ed=\min\{A-1,b^2\} st=Cb2,ed=min{A1,b2}
即求
∑ b = 1 B ( C − 1 ) ( e d − s t + 1 ) ∑ a = s t e d − ⌊ b 2 a ⌋ \sum_{b=1}^B(C-1)(ed-st+1)\sum_{a=st}^{ed}-\lfloor{b^2\over a}\rfloor b=1B(C1)(edst+1)a=stedab2
显然可以直接枚举 b b b ,数论分块求后面的部分。
然后你就T了。
然后你会发现出题人为了卡你,肯定会把 A A A 设得很大,使得你的分块上限总是 b 2 b^2 b2 。所以我们可以事先预处理出每个 b 2 b^2 b2 在分块时每段的值,做的时候只要统计 s t , e d st,ed st,ed 所在段上的某些值就行了。这样统计所需的时间在上限接近 b 2 b^2 b2 的情况下是很小的。

代码

Expected GCD

水水的套路题。
考虑统计所有方案的 gcd ⁡ \gcd gcd 的和。
∑ i 1 = 1 n ∑ i 2 = i 1 + 1 n ⋯ ∑ i k = i k − 1 + 1 n ( i 1 , i 2 , ⋯   , i k ) \sum_{i_1=1}^n\sum_{i_2=i1+1}^n\cdots\sum_{i_k=i_{k-1}+1}^{n}(i_1,i_2,\cdots ,i_k) i1=1ni2=i1+1nik=ik1+1n(i1,i2,,ik)
∑ d = 1 n d ∑ i 1 = 1 ⌊ n d ⌋ ⋯ ∑ i k = i k − 1 + 1 ⌊ n d ⌋ [ ( i 1 , i 2 , ⋯   , i k ) = 1 ] \sum_{d=1}^nd\sum_{i_1=1}^{\lfloor{n\over d}\rfloor}\cdots\sum_{i_k=i_{k-1}+1}^{\lfloor{n\over d}\rfloor}[(i_1,i_2,\cdots ,i_k)=1] d=1ndi1=1dnik=ik1+1dn[(i1,i2,,ik)=1]
∑ d = 1 n d ∑ i 1 = 1 ⌊ n d ⌋ ⋯ ∑ i k = i k − 1 + 1 ⌊ n d ⌋ ∑ t ∣ i 1 , t ∣ i 2 , ⋯   , t ∣ i k μ ( t ) \sum_{d=1}^nd\sum_{i_1=1}^{\lfloor{n\over d}\rfloor}\cdots\sum_{i_k=i_{k-1}+1}^{\lfloor{n\over d}\rfloor}\sum_{t|i_1,t|i_2,\cdots ,t|i_k}\mu(t) d=1ndi1=1dnik=ik1+1dnti1,ti2,,tikμ(t)
∑ d = 1 n d ∑ t = 1 ⌊ n d ⌋ μ ( t ) ( ⌊ n d t ⌋ k ) \sum_{d=1}^nd\sum_{t=1}^{\lfloor{n\over d}\rfloor}\mu(t){\lfloor{n\over dt}\rfloor\choose {k}} d=1ndt=1dnμ(t)(kdtn)
G = d t G=dt G=dt
∑ G = 1 n ( ⌊ n G ⌋ k ) ∑ d ∣ G d ⋅ μ ( G d ) \sum_{G=1}^n{\lfloor{n\over G}\rfloor\choose {k}}\sum_{d|G}d·\mu({G\over d}) G=1n(kGn)dGdμ(dG)
f ( x ) = ∑ d ∣ x d ⋅ μ ( x d ) f(x)=\sum_{d|x}d·\mu({x\over d}) f(x)=dxdμ(dx) ,可以 O ( n ) O(n) O(n) O ( n log ⁡ n ) O(n\log n) O(nlogn)(偷懒) 求出。
∑ G = 1 n ( ⌊ n G ⌋ k ) f ( G ) \sum_{G=1}^n{\lfloor{n\over G}\rfloor\choose {k}}f(G) G=1n(kGn)f(G)
然后似乎就可以愉快地套数论分块了?
然后你就又T了。
实际上你还需要一些卡常技巧。(毒瘤出题人)
具体来说:

  • 对于 G ≤ n G\le \sqrt n Gn ,此时每个 G G G 对应的 ⌊ n G ⌋ \lfloor{n\over G}\rfloor Gn 是不同的,直接枚举。
  • 对于 G > n G>\sqrt n G>n ,我们可以转而枚举 ⌊ n G ⌋ \lfloor{n\over G}\rfloor Gn,只要把上面的式子变换一下就可以了。

这样只要做 2 2 2 1 − n 1-\sqrt n 1n 的枚举,而且运算量大幅度降低了。然后就可以通过此题了。

代码

Doofish Set
可以发现原图的补图中每对有边相连的点一定永远在同一组中。于是有解当且仅当补图中每个连通块都是一个团。
把这些团缩起来,就转化为原图中所有点间都有边相连的问题,每次平均分成两组就可以了。
至于求补图中每个连通块的方法,可以先找出原图中度数最小的点 x x x ,那么和 x x x 有边的点数不超过 min ⁡ ( n , ⌊ m n ⌋ ) ≤ 200000 \min(n,\lfloor{m\over n}\rfloor)\le\sqrt{200000} min(n,nm)200000 。然后把和 x x x 没边的点缩起来,再枚举每个和 x x x 有边的点和其他点连即可。
时间复杂度 O ( n M + n log ⁡ n ) O(n\sqrt{M}+n\log n) O(nM +nlogn)

代码
Power Sum && Dodgers
挖坑

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值