zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:求和(数学)

    题目传送门(内部题107)


    输入格式

      一行五个正整数$x_1,y_1,x_2,y_2,m$


    输出格式

      输出一个整数,为所求的答案对$m$取模后的结果。


    样例

    样例输入:

    2 1 5 3 10007

    样例输出:

    54


    数据范围与提示

      对于$20\%$的数据,满足$x_2,y_2,mleqslant 1,000$。
      对于$40\%$的数据,满足$x_2,y_2,mleqslant 100,000$。
      对于$70\%$的数据,满足$x_2,y_2,mleqslant 10^9$。
      对于$100\%$的数据,满足$1leqslant x_2,y_2,mleqslant 10^{18},1leqslant x_1leqslant x_2,1leqslant y_1leqslant y_2$。


    题解

    先来化式子,对于$sum limits_{i=x_1}^{x_2}sum limits_{i=y_1}^{y_2}d_{i,j}$,其左上角为$x_1+y_1-1$,那么其右上角为$x_1+y_1+(y_2-y_1)-1$。

    不妨设$y_2-y_1+1=len$。

    那么根据等差数列求和公式,第一行的和就是$frac{[2 imes (x_1+y_1-1)+len-1] imes len}{2}$,因为需要取模,而模数不是质数,我们又不想打$CRT$;但是我们发现如果$len$是一个奇数,那么$[2 imes (x_1+y_1-1)+len-1]$就可以除$2$,否则$len$就可以除$2$。

    现在我们求出了$sum limits_{i=y_1}^{y_2}d_{x_1,i}$,不妨设其为$sum$,现在接着来考虑$sum limits_{i=x_1}^{x_2}sum limits_{i=y_1}^{y_2}d_{i,j}$该如何求。

    发现每行之间的差也呈等差数列,且公差为$len$(因为每一个数都比上一行大$1$),那么最后一行的和就是$sum+(x_2-x_1) imes len$,再根据等差数列求和公式得到答案为$frac{[2 imes sum+(x_2-x_1) imes len] imes (x_2-x_1+1)}{2}$,同样可以根据上面的方法避免逆元。

    但是发现可能会乘爆$long long$,一种避免高精的方法就是使用慢速乘,附一份代码:

    long long qmul(long long x,long long y)
    {
    	long long res=0;
    	while(y)
    	{
    		if(y&1)res=(res+x)%mod;
    		x=(x+x)%mod;
    		y>>=1;
    	}
    	return res;
    }
    

    时间复杂度:$Theta(log m)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    long long x,y,x2,y2,m;
    long long qmul(long long x,long long y)
    {
    	long long res=0;
    	while(y)
    	{
    		if(y&1)res=(res+x)%m;
    		x=(x+x)%m;
    		y>>=1;
    	}
    	return res;
    }
    int main()
    {
    	scanf("%lld%lld%lld%lld%lld",&x,&y,&x2,&y2,&m);
    	long long len=y2-y+1,sum,ans;
    	if(len&1)sum=qmul(((x+y-1)+((len-1)>>1))%m,len);
    	else sum=qmul((qmul(x+y-1,2)+len-1)%m,len>>1);
    	if((x2-x)&1)ans=qmul((qmul(sum,2)+qmul(x2-x,len))%m,(x2-x+1)>>1);
    	else ans=qmul(sum+qmul((x2-x)>>1,len),x2-x+1);
    	printf("%lld",ans);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    logstash multiple piplines 配置方式
    filter-mutate过滤插件
    redis主从复制
    redis sentinel(哨兵)
    mongodb replica-set
    Linux入门篇(五)——Shell(一)
    Linux入门篇(四)——Vim的使用与Bash
    Linux入门篇(三)——文件与目录
    Linux入门篇(二)——文件
    Linux入门篇(一)——基本命令
  • 原文地址:https://www.cnblogs.com/wzc521/p/11775074.html
Copyright © 2011-2022 走看看