1 solutions

  • 1
    @ 2023-1-12 22:07:52

    这个题可以通过找数学规律的思想,分别计算出前L-1项的和前R项的,利用前缀和思想相减即可得出答案。

    此外,这道题如果直接暴力,可以获得36%的分数,使用普通的前缀和优化(就是使用前缀和分别计算前L-1和前R天所完成的工作总量,相减就能得到[L,R]时间内完成的工作量),可以获得72%的分数。代码就不放了,有兴趣的同学可以自己尝试一下。

    下面是这个题的正解,也就是开头所提出的正确做法: 通过观察,我们可以发现:学长所完成的工作量是单调递增的,正好是有连续n天完成的工作量是n,即有1天完成的工作量为1,有2天完成的工作量为2,有n天完成的工作量为n……于是,完成n项工作的最后一天恰好是1+2+……+n,即第n*(n+1)/2天。于是,我们便可以通过下面的公式得知第L-1天和第R天所完成的工作量。在公式中用ans表示,而n表示的则是在ans以内最大的可以完成n项工作的最后一天。

    ((n+1)n)/2=ans((n+1)*n)/2=ans

    即:

    n2+n2ans=0n^2+n-2*ans=0;

    这是一个一元二次方程组,我们可以使用初中的知识,解出这个方程即可。

    x=b±√∆2a【公式Ix={-b±√∆\over 2*a} 【公式I】

    由于正好是有连续n天完成的工作量是n,假设将每连续的n天分为1组,前n组的总工作量便是:

    S=12+22+32+n2;S=1^2+2^2+3^2+……n^2;

    可以由立方和公式求出结果:

    S=n(n+1)(2n+1)6【公式IIS={n*(n+1)*(2*n+1)\over6} 【公式II】

    再利用

    ansn(n+1)2【公式IIIans-{n*(n+1)\over2} 【公式III】

    求出第(n+1)组中剩下的天数,每天乘上n+1,便可求出第1天到第ans天的总工作量G。用1到R的结果减去1到L-1的结果即可得出答案~

    $$G={n*(n+1)*(2*n+1)\over6} +(ans-{n*(n+1)\over2})*(n+1) 【公式IV】 $$

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    long long func(long long s)
    {
    	long long n,ans,P;
    	double a=1,b=1,c=-(2*s);
    	double N=(-b+sqrt(b*b-4*a*c))/(2*a);//公式I
    	n=(long long)N;
    	P=(1+n)*n/2;
    	ans=(s-P)*(n+1)+n*(n+1)*(2*n+1)/6;//公式IV,s-p为公式III,之后为公式II,加起来求和即可
    	return ans;
     } 
    
    int main()
    {
    	int q;
    	scanf("%d",&q);
    	while(q--)
    	{
    		long long l,r;
    		long long ansl=0,ansr=0;
    		scanf("%lld %lld",&l,&r);
    		ansl=func(l-1);
    		ansr=func(r);//求L-1和R
    		long long ans=ansr-ansl;
    		printf("%lld\n",ans);
    	}
    	return 0;
    }
    
    • 1

    Information

    ID
    6685
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    9
    Tags
    # Submissions
    93
    Accepted
    7
    Uploaded By