zoukankan      html  css  js  c++  java
  • 「考试」省选54

    好难啊。

    T1
    数论题。
    我一开始以为是什么(burnside)之类的。
    看来全是(yy)了。
    我们可以把四个排列(A,B,C,D)中的每一个位置都在四张图上连边((i,P_i))
    这样会形成若干环。
    那么我们要搞得所有步全都是这样的:
    (G_A,G_B,G_C,G_D)中分别选四个圈出来。
    设他们的大小为(A,B,C,D),那么必须要把其中的(ABCD)个点全遍历一次才可以。
    那么我们只需要考虑长度为2的步数是多少即可。
    这些步是什么样的呢?
    就是不同时在四个圈上顺时针走。
    那么四个圈上不重复的走一次能够遍历到的不同的点的个数是(lcm(A,B,C,D))
    也就是说走完(lcm(A,B,C,D))之后,必须要跳圈,也就是走长度为2的步子一次。
    由于我们能够保证既定四个圈上不同的起点使得任意次的圈路遍历到的节点各不相同。
    那么也就是说。
    对于枚举到的某四个圈来说,他们的走过大小为2的步子的个数为(frac{ABCD}{lcm(A,B,C,D)})
    (P[i])为排列(P)中长度为(i)的个数。
    那么我们需要统计的就是。

    [sumlimits_{i=1}^{n}sumlimits_{j=1}^{n}sumlimits_{k=1}^{n}sumlimits_{l=1}^{n}A[i]B[j]C[k]D[l]frac{ijkl}{lcm(i,j,k,l)} ]

    这个东西还是挺难算的。
    考虑莫比乌斯反演结合暴力计算。
    设阈值(lim=10^6)
    那么我们考虑小于等于(lim)的部分莫比乌斯反演,剩下的直接暴力(稍微有点卡常)。
    考虑(meet in the middle)
    我们把(A,B)(C,D)分别结合。
    考虑把这个式子化一化。

    [egin{aligned} A[i]B[j]C[k]D[l]frac{ijkl}{lcm(i,j,k,l)}&=A[i]B[j]C[k]D[l]frac{lcm(i,j)lcm(k,l)}{lcm(i,j,k,l)}frac{ij}{lcm(i,j)}frac{kl}{lcm(k,l)}\ &=A[i]B[j]gcd(i,j)C[k]D[l]gcd(k,l)gcd(lcm(i,j),lcm(k,l))\ end{aligned} ]

    这样我们把关键字求和,按照(lcm(i,j))为关键字,把(A[i]B[j]gcd(i,j))暴力求和。
    怎么求和?
    暴力求和。
    为什么可以暴力。
    我们知道对于一个排列来说,各个环的长度之和为(n),那么不同的环长个数为(sqrt{n})个。
    所以我们只需要(O(n))地合并两个排列。
    最后考虑用莫比乌斯反演合并((A,B))((C,D))
    也就是

    [egin{aligned} sumlimits_{i=1}^{lim}sumlimits_{j=1}^{lim}F[i]G[j]gcd(i,j)&=sumlimits_{d=1}^{n}dsumlimits_{d|i}F[i]sumlimits_{d|j}G[j][gcd(i,j)=1]\ &=sumlimits_{d=1}^{lim}dsumlimits_{d|i}F[i]sumlimits_{d|j}G[j]sumlimits_{g|gcd(i,j)}mu(g)\ &=sumlimits_{d=1}^{lim}dsumlimits_{g=1}^{lim}mu(g)sumlimits_{dg|i}F[i]sumlimits_{dg|j}G[j]\ T&=dg\ H(T)&=sumlimits_{T|i}F[i]sumlimits_{T|j}G[j]\ &=sumlimits_{T=1}^{lim}H(T)sumlimits_{d|T}dmu(frac{T}{d})\ mu*id&=varphi\ sumlimits_{T=1}^{lim}H(T)sumlimits_{d|T}dmu(frac{T}{d})&=sumlimits_{T=1}^{lim}H(T)varphi(T)\ end{aligned} ]

    这个算法是(O(limln lim))的。
    大于(lim)的部分直接暴力做掉就可以了。

    T2
    是一个树形(dp)
    我们考虑一个这样的(dp)
    (dp[x][j])为节点(x)的子树中放置的关键点个数为(j)个的最优答案,注意(子树中不包括点(x),我们可以认为剩下的所有节点均在(x)处)。
    其中(j)的大小是小于其子树大小的,因为外面的点是可以进来的。
    那么我们设(su[x])(x)中的关键点个数。
    则有转移:

    [dp[x][i]=dp[x][i]+dp[t][0]+su[t] ]

    表示(t)这个儿子之中并没有存在节点,那么其中的所有关键点必须上传,也就是走(su[t])步。

    [dp[x][j+k]=min(dp[x][j+k],dp[t][k-1]+abs(su[t]-k)+dp[x][j]) ]

    表示我枚举当前儿子含有的关键点个数是多少,根据究竟是进来了节点还是出去了节点用计算贡献,所以用绝对值来计算。
    样对于每一个根节点都计算一次最优解即可。
    树形(dp)复杂度是(O(n^2)),那么算上枚举根的复杂度是(O(n^3))了。

    T3
    性质1:

    [F(x+2C)=F(x)+2C ]

    证明:

    [egin{aligned} y&=2F(x)-x+1\ F(y)&=F(x)+C\ F(y)+C&=F(x)+2C\ F(2F(y)-y+1)&=F(x)+2C\ 2F(y)-y+1&=2F(x)+2C-2F(x)+x-1+1=x+2C\ F(x+2C)&=F(x)+2C\ end{aligned} ]

    这也意味着我们的值必然是(F(x)=t+nC)这种形式的。

    性质2:

    [a+b=2t+1,F(a)=t+nC ightarrow F(a)+F(b)=2t+C ]

    证明:

    [egin{aligned} F(2F(a)-a+1)&=F(a)+C\ F(2(t+nC)-a+1)&=t+nC+C\ F(2t+2nC-a+1)&=t+nC+C\ F(2t-a+1)+2nC&=t+nC+C\ F(b)&=t-(n-1)C\ F(a)+F(b)&=2t+C\ end{aligned} ]

    这两个性质很好。
    我们首先考虑按照(X_imod 2C)进行分组。
    分成(2C)组。
    那么一个函数值只要确定了同组中的某一个的值就可以确定其值。
    同时我们发现有限制的两组,必然是满足(a+b=2t+1)的。
    也就是说,(a,b)的奇偶性必然不同。
    这导出一个二分图模型。
    按照模意义下的余数的奇偶性二分。
    然后形成的这张图,根据(t)的不同,我们可以发现必然是一个奇数对应一个偶数,而这种对应取决于(F(a)=t+nC)(t)
    同时由于一个(X)在函数中仅对应一个(Y)那么我们可以了解到,一个数仅仅是对应一个数的,因为这个(t)是有唯一解的。
    函数要求答案必须是一种完美匹配。
    这样我们搞一个二分图带权匹配。
    跑个最小费用最大流即可。
    怎么建图?
    (a ightarrow b)这条边的边权设置为1,费用设为这些点关于这两个点匹配的最小代价。
    把点按(X_i)(2C)分组之后,考虑这样一个计算费用的方法。
    (a=2i,b=2j+1)
    那么对于一个点的费用可以这样来表示:

    [|F(X_i)-Y_i| ]

    如果是函数值的话,我们可以发现这样一件事情,当(F(a)+=C),那么(F(b)-=C)
    那么设(W_i=F(X_i)-Y_i)
    最终的费用就是:

    [sumlimits_{i=1}^{num}|W_i+nC| ]

    如果是(a)那边的权值的话。
    因为(i+j=t)
    我们设:(W_c=i+j+X_c-a-Y_c)
    如果是(b)那边的权值的话。
    由于最终表达式带了绝对值,而且(F(b))(-=C)的。

    [W_c=-(i+j+X_c-b+C-Y_c) ]

    这样我们考虑最终的表达式。
    按照(W_i)排序,最终的(nC)大小一定是中位数附近的。
    这样我们就可以快速的得到费用的最小值了。
    然后我们按照这样的费用建造带权二分图,然后跑最小费用最大流。
    由于一定存在完美匹配,所以最小的费用就是答案了。

  • 相关阅读:
    【QT】对话框打开图像并用QPixmap显示
    【QT】打开文件对话框,选择路径下文件
    狄拉克下采样
    Linux 安装JDK(jdk-8u121-linux-x64.tar.gz)
    Linux 命令安装bin文件
    Python3 tesseract加载chi_sim异常停止工作
    Python3 pip出现Fatal error in launcher: Unable to create process using '"'
    Python3 判断文件和文件夹是否存在、创建文件夹
    Python3 itchat实现微信定时发送群消息
    Python3 实现(wxpy)用微信自动定时给朋友定时推广
  • 原文地址:https://www.cnblogs.com/Lrefrain/p/12568924.html
Copyright © 2011-2022 走看看