UOJ Logo Trinkle的博客

博客

共找到 2 篇包含 “数学” 标签的博客:

圆的反演

2015-07-11 20:16:47 By Trinkle

Codechef July Challenge 2015 » NTHCIR

虽然我知道在比赛还没结束前挂题解不好,但是还是想骗一发访问量

题目大概是这样的:

有很多圆,满足 Cn(n4)C1,C2,,Cn1 都相切,C3 与 C1,C2 相切,C2 与 C1 相切,图形如下:

现已知 r1,r2,r3,r4,求 rn。询问数<=1000w,n109,时限 1.5s

例如:当 r1=6,r2=r3=3,r4=2 的时候,圆大概长这样:

 

圆的反演是什么呢?

我们先选定一个点 O为反演中心,以 O 为圆心,半径为 r 画一个圆。然后对于平面上的点 PP,如果 PP 在以 O 为起点的射线上,并且 |OP||OP|=r2,那么就说 PP 互为反演点。

所以圆外的点反演一下会到圆内,圆内会到圆外,圆上则不变。

我找了 GeoGebra 来玩玩,效果差不多是长下面这个样子的:

Screenshot%20from%202015-07-11%2018:55:5

反演中心为坐标原点,点 H 在直线上移动,点 J 为射线 AH的焦点,点 I 为点 H 的反演点。

可以看到,一条不过反演中心的直线反演之后变成了一个过反演中心的圆。而且直线和两个圆两两相交。

由于反演的可逆性,这个圆反演一下就变成了一条直线啦~

Screenshot%20from%202015-07-11%2019:04:0

一个不过反演中心的圆反演以后是一个以反演中心位似的圆。

从上面的图来看,显然两个圆是反过来对应的,并不是直接位似。还有切记,圆心反演完以后并不是反演完的圆的圆心,比如上面的点 HI

再来一个好玩点的:

Screenshot%20from%202015-07-11%2019:21:2

抛物线反演一下,不知道变成了什么。。。右边的黑线是 2x,然而不能拟合。

Screenshot%20from%202015-07-11%2019:25:4

然后稍微往下移一点就变成了心型线!

Screenshot%20from%202015-07-11%2019:31:4

椭圆好像跟上面两种差不多,不是太好玩。

Screenshot%20from%202015-07-11%2019:36:1

双曲线反演一下变成了 ...

 

我们不妨把样例反演一下变成下面这样:

Screenshot%20from%202015-07-11%2019:43:5

由于反演前后的几何性质是不会发生改变的,比如反演前两个圆相切,反演完以后他们两个还是相切,只不过可能不是圆与圆相切而是直线与圆相切之类的,因此我们可以像这张图这样建立反演中心,圆 C1,C2 反演完以后就变成了两条直线,而 C3,C4, 反演完之后,由于没过反演中心,所以还是圆;又因为它们都与圆 C1,C2 相切,所以反演以后的圆统统都被夹在了两条直线里面,大小都一样,而且一个挨着一个。

这里详细讲了怎么求一个圆的反演

然而我觉得如果不会求的话,可以随便找圆上的三个点,然后把这三个点反一下,然后再以这三个点画个圆就好了,简单粗暴= =

注意不能直接求圆心。原因在上面第二张截屏。

于是这题的解法已经十分明了了:先把 C1,C2 反成直线,解三角形解出 C3 的位置,然后反成小圆,看一下 C4 塞哪里符合题意,然后就可以 O(1) 求出第 n 个圆反演完以后的圆,直接反回去就好了。

BZOJ3157/3516/4126 国王奇遇记 题解

2015-06-06 19:51:54 By Trinkle

本题按时间复杂度的不同共有三种解法。

Sol-1 O(m2log(n))

f(n,k)=i=1nikmi

f(n+1,k)=i=1n+1ikmi=m+i=2n+1ikmi=m+mi=1n(i+1)kmi=m+mi=1nj=0kCkjijmi=m+mj=0kCkji=1nijmi=m+mj=0kCkjf(n,j)

f(2n,k)=i=12nikmi=i=1nikmi+i=n+12nikmi=f(n,k)+i=1n(i+n)kmi+n=f(n,k)+mni=1nmij=0kCkjijnkj=f(n,k)+mnj=0kCkjnkji=1nijmi=f(n,k)+mnj=0kCkjnkjf(n,j)

所以我们只要花O(m2)的时间就能从n转移到n+1或者2n,类似快速幂的思想就能在O(m2log(n))的时间内解决这题。

Sol-2 O(m2)

好像网络上的题解都是这个复杂度。

f(k)=i=1nikmi

(m1)f(k)=i=1nikmi+1i=1nikmi=i=2n+1(i1)kmii=1nikmi=nkmn+1+i=1nmi[(i1)kik]=nkmn+1+i=1nmij=0k1Ckjij(1)kj=nkmn+1+j=0k1Ckj(1)kji=1nijmi=nkmn+1+j=0k1Ckj(1)kjf(j)f(k)=nkmn+1+j=0k1Ckj(1)kjf(j)m1 特判m=1的情况,当m1时直接用上面的式子O(m2)转移。

Sol-3 O(m)

Orz完杜教的ppt才懂

G(n)=i=0n1immi,注意这里只加到n1

然后把m很小的时候的公式找出来:

m=2  G(n)=2n(n24n+6)6m=3  G(n)=3n(4n318n2+36n338)+338m=4  G(n)=4n(27n4144n3+360n2528n+38081)38081m=5  G(n)=5n(128n5800n4+2400n34600n2+5700n3535512)+3535512m=6  G(n)=6n(3125n622500n5+78750n4183000n3+305550n2340020n+18971410625)18971415625

//公式最后一项的有理数还是一个神奇的数列

根据上面这些公式,不难得出答案的式子一定是长这样的:

G(n)=mnFm(n)Fm(0)

其中Fm(n)是一个m次多项式(代入n后的值),形如c0nm+c1nm1+...+cm1n+cm

归纳法证一下发现结论是对的。

所以

G(n+1)G(n)=nmmn=mn+1Fm(n+1)mnFm(n) nm=mFm(n+1)Fm(n) Fm(n+1)=nm+Fm(n)m

Fm(0)=x,则Fm(1)~Fm(m+1)都能通过上面的递推式变成形如Ax+B的形式。

由于Fm(n)是一个次数为m的多项式(代入n后的值),所以有下面这个式子:

i=0m+1(1)iCm+1iFm(i)=0

为什么呢?

首先,Fm(i)是可以线性表示成若干个组合数之和,于是我们只要证明

km,i=0m+1(1)iCm+1iCik=0

注意到i的范围只能是[k,m+1],否则后面那坨东西直接变成0。

i=km+1(1)iCm+1iCik=i=km+1(1)i(m+1)!i!(m+1i)!i!k!(ik)!=(m+1)!(m+1k)!k!i=km+1(1)i(m+1k)!(m+1i)!(ik)!=Cm+1ki=km+1(1)iCm+1kik=Cm+1ki=0m+1k(1)ikCm+1ki=(1)kCm+1k(11)m+1k=0

于是这个鬼畜的结论就证完啦~对任意m次多项式都能用~

然后就能根据这个式子列方程,就能把Fm(0)给解出来。

然而题目不是叫你求Fm(0),而是求mnFm(n)Fm(0)

nm的时候,好办,把之前用到的Fm(n)=A(n)Fm(0)+B(n)直接算一下,然后就能得到答案了。

n>m的时候,?

假设我们已经求出了Fm(0),Fm(1),...,Fm(m)

Fm(n)=k=0mCnkak

经过二项式反演可得ak=j=0k(1)kjCkjFm(j)

Fm(n)=k=0mCnkj=0k(1)kjCkjFm(j)=j=0mFm(j)k=jm(1)kjCnkCkj=j=0mFm(j)k=jm(1)kjn!k!k!(nk)!j!(kj)!=j=0mFm(j)k=jm(1)kjn!(nj)!(nk)!j!(kj)!(nj)!=j=0mFm(j)k=jm(1)kjCnjCnjkj=j=0mFm(j)Cnjk=0mj(1)kCnjk=j=0mFm(j)Cnj(1)mjCnj1mj=j=0mFm(j)(1)mjn!(nj1)!j!(nj)!(mj)!(nm1)!=n!(nm1)!j=0mFm(j)(1)mj1j!(mj)!(nj)=j=0mFm(j)(1)mjn(n1)...(nm)j!(mj)!(nj)

n(n1)...(nm)nj可以用一个前缀乘积和一个后缀乘积优化成O(m)的预处理复杂度。

所以只要花O(m)的时间就好了。

上面有一步用到了这个式子(第六行到第七行): i=0k(1)iCni=Cn0Cn1+...=Cn10Cn1+...=Cn11+Cn2...=Cn12Cn3+...=(1)kCn1k

复杂度分析:求1~m+1的所有阶乘、逆元、阶乘逆元以及im都能做到O(m)的时间复杂度。

i[1,m]Fm(i)也只要用线性复杂度。

nm的时候,只要用O(1)的时间得到答案。

n>m的时候,照着最后一个式子求。前面的乘数花O(m)的时间算,后面的n(n1)...(nm)nj,1j!1(mj)!直接O(1)

打了一个下午题解终于把这个坑给填了233

其实我已经在这篇blog里面贴了代码,然而只有神犇才能看得见。