zoukankan      html  css  js  c++  java
  • 暑假娱乐赛·题解

    由于出题人的疏忽,导致T2和T3分别有一个数据造错,造成了大家不必要的麻烦,对此十分抱歉。

    这里写一下三道题的题解:

    A--LJJ爱数数

    题目链接:https://www.luogu.org/problemnew/show/P4844

    题目简述:求出有多少个正整数三元组{a,b,c},满足a,b,c<=n,a,b,c三个数的最大公约数为1,且1/a+1/b=1/c。

    数据范围:n<=1e12

    tag:本题原型来自中等数学2011年第1期,进行了一番改编。

    20分:枚举a,b,O(1)算出c,统计答案

    100分:

    方法一:

    化简后得到(a+b)c=ab,设g=(a,b),A=a/g,B=b/g,则g(A+B)c=ABg^2,即(A+B)c=ABg

    由题目已知条件:(a,b,c)=1,即(g,c)=1,g|(A+B)c,故g|(A+B),

    设(A+B)/g=AB/c= k ∈ Z,

    若k>1,因为A,B互质,所以k|A或k|B,则A+B不能被k整除,矛盾。因此k=1。

    故充要条件为:1<=a,b,c<=n,a+b=g^2,c=ab/g^2。

    枚举g,则可得A+B=g。用莫比乌斯反演求出一定范围内与g互质的数的个数即可。

    写程序的过程中,你会发现,枚举1到sqrt(2n)的g之后,只需枚举g的约数。

    所以时间复杂度是O(sqrt(n)log(sqrt(n)))

    方法二:(PJY提供的此方法十分巧妙)

    可以化简得到:(a+b)c=ab,于是ab-bc-ac+c^2=c^2,所以(a-c)(b-c)=c^2

    设a-c=km^2,b-c=kn^2,则c=kmn。

    若k>1,(a,b,c)=(km^2+kmn, kn^2+kmn, kmn)≠1,矛盾。故k=1

    由此我们知道a-c=m^2,b-c=n^2是完全平方数。

    因为(a,b,c)=(m(m+n),n(m+n),mn)=((m+n)*(m,n),mn)=1,所以(m,n)=1

    故充要条件为1<=a,b,c<=n,a-c, b-c是完全平方数,c^2=(a-c)(b-c),(a-c,b-c)=1

    枚举(a-c),用莫比乌斯反演求出一定范围内与sqrt(a-c)互质的数的个数即可。时间复杂度是O(sqrt(n)log(sqrt(n)))

    源码:

    方法一:https://paste.ubuntu.com/p/mXF2bvXdy7/

    方法二:https://paste.ubuntu.com/p/yn5NddzNjj/ 

    B--LJJ爱数树

    题目链接:https://www.luogu.org/problemnew/show/P4845

    题目简述:在一棵n个节点的树上的k个点处放k个摄像头。每个摄像头可以看到与之树上距离<=r的点。

    使得被看到的点的w[i]之和最大。

    数据范围:k<=n<=1000,w[i]<=1e6

    tag:

    乱搞做法一:如果一个一个放摄像头,每一次把当前w[i]和最大话,那样例一就过不了

    乱搞做法二:如果直接假定关于摄像头个数k的函数f(k)是凸函数,那样例二就过不了(因为这个结论是错误的)

    10分:枚举2^n种情况(还可以用位运算优化)。

    另外20分(k<=2):做法可能有多种,可以暴力枚举两个点,然后用点分或dsu求每种情况的答案。

    40分:暴力dp,定义dp数组f[i][j][k][l],

    f[i][j][k1][k2]表示第i个节点的子树处理完毕,子树中放了j个摄像头。

    期望被观测,但未被观测的最远的点距离ta为k1;最近的摄像头离ta距离为k2。

    该dp复杂度或许是O(n^4)吧,(没实现过不清楚)

    100分:接着上述40分的题解讲。

    我们在dp的过程中,初始化每个节点有三种状态:什么都没发生;放有一个摄像头;虽没放摄像头,但这个点之后会被观测到。

    所以dp的过程中,就决定了每个点是否计入答案。其有用的信息为:子树中离点i最近的摄像头的距离,子树中离点i最远的期望被观测的

    点的距离。且信息有用当且仅当距离<=r,因为摄像头的观测范围就是r。

    如果两个信息同时存在,那么可以忽略摄像头的信息。

    这里证明一下:

    设最远的期望被观测的点为a点。最近的摄像头为b点。所以dis(a,b)>r。

    之后一定有一个摄像头c点,使得dis(a,c)<=r。那么显然dis(c,i)<dis(b,i)。显然,摄像头b能观测到的在 i 子树外的点,c都能观测到。

    所以可以忽略b的信息。

    所以理所当然地,可以把dp数组写成f[i][j][k](原先第三维和第四维压缩成一维)

    之后的dp,可能细节有些繁琐。导致标程可读性差。所以题解里就不阐述了。

    这样还不够,因为n<=1000。

    我们还需要证明一下:当k*r>=n时,所有的点都能够被观测到。

    随便选一个点提根。取深度最深的点,如果深度<=r,直接选择根节点放摄像头。

    若深度dep>r,选择与该点距离r的祖先,选择该祖先放摄像头,这样相当于花费一个摄像头砍去了点数>=r的一个子树。

    故容易证明k*r>=n时,所有点都能观测到。

    所以,k*r<n时,枚举点i,依次把它的儿子所代表的子树合并起来,复杂度是min(k,size[a])*min(k,size[b])*r。

    总复杂度可以证明是n*k*r<n^2。(不详细讲证明了)

    源码:

    标程:https://paste.ubuntu.com/p/gdFgv42mzf/

    翠竹叶飞的代码:https://paste.ubuntu.com/p/4jJyCCyddq/

    C--LJJ爱数书

    题目链接:https://www.luogu.org/problemnew/show/P4846

    题目简述:

    一个序列A,每次操作可以使一段连续的区间加1或减1并对K取模,定义F(A,K)表示最少的操作次数使得序列的所有元素都变为0。

    输入长度为n的序列A,m次询问F(A[x][y],K)的值。

    数据范围:

    n<=200000, m<=100000, k<=1e9

    tag:

    唯一一道数据结构题,所以思路不是那么难。只要你会50分,就可以轻松优化到100分。

    10分:搜索+剪枝

    30分:先考虑单组询问求F(A,K)。为了方便之后处理,首尾加 0 。

    设长度变为N=n+2

    我们先考虑如果操作中每次加一、减一后不取模。若A[i]∈Z(可能是负数)。

    先对A差分 -> 设B[i]=A[i]-A[i-1](对于1<i<=n),显然B[2]+B[3]+...+B[N]=0

    每次操作等同于,B[i]加一,B[j]减一( 1<i,j<=N ),目标是将所有的B[i]变为0。

    若未达到目标,因为所有的B[i]之和为0。一定存在B[i]>0,B[j]<0。

    所以一定存在一次操作,使得B[i]的绝对值的和减2。

    由此我们知道,此时最小操作次数是[abs(B[2])+abs(B[3])+...+abs(B[N])] / 2。(此处abs表示绝对值)

    现在题中操作为每次加一、减一后对K取模。所以等同于,先将A数组的某些元素加或减K的倍数。

    等同于我们先对差分数组B中某些元素加或减K(根据之前最小操作次数的公式,显然加减范围不会超过K),并维持B[2]+B[3]+...+B[N]=0。

    求这样的情况下,[abs(B[2])+abs(B[3])+...+abs(B[N])]/2 的最小值。

    容易实现单次询问O(n^2) dp。

    50分:接着30分的题解讲,我们要对差分数组的某些数值加K或减K,并维持B[2]+B[3]+...+B[n]=0。

    设在S个位置加K,在S个位置减K。(这2S个位置不重复)

    显然,我们只会在小于0的位置加K,在大于0的位置减K。所以前者和后者一定不重复。

    对于小于0的数 (-a),对其加K可以使代价减少 (2a-K)。

    对于大于0的数(a),对其减K可以使代价减少 (2a-K)。

    所以,对要加K和要减K的位置,选2a-K前S大的位置,(a是其绝对值)

    容易做到单次询问O(n),总复杂度O(mn)。

    100分:接着50分的题解讲,显然,我们可以二分这个K,求区间第K大和前K大和即可。(这里不再赘述)

    使用主席树或划分树可做到复杂度O(mlog^2n)。

     源码:https://paste.ubuntu.com/p/mYvBWMJ5vx/

  • 相关阅读:
    android学习计划2
    在ubuntu12.04下编译android4.1.2添加JNI层出现问题
    android原生系统裁剪
    LM393,LM741可以用作电压跟随器吗?
    android-86-Can't create handler inside thread that has not called Looper.prepare()
    三星 PMU NXE2000,x-powers的AXP228,NXE2000
    当函数没有return时错误
    Perl OOP
    ORA-01031: 权限不足
    Oracle 10g 10.2.0.1 在Oracle Linux 5.4 32Bit RAC安装手冊(一抹曦阳)
  • 原文地址:https://www.cnblogs.com/Blog-of-Eden/p/9367521.html
Copyright © 2011-2022 走看看