zoukankan      html  css  js  c++  java
  • SCAU 10674 等差对

    10674 等差对

    时间限制:1000MS  内存限制:65535K 提交次数:0 通过次数:0

    题型: 编程题   语言: 无限制

    Description

       今天是一个特别的日子,百年一遇的光棍节,2011.11.11,xym收到一个装着礼物的信封,是一位mm的XX书,里面是两个棒棒糖和一封信。
    信里是一道智力题:
        定义如果<x0,y0>和<x1,y1>满足x0-x1=y0-y1,则称这两个为等差对。
    mm的问题是,问在<x,y>(0<=x,y<=n)<0,0>,<0,1>…<1,0>,<1,1>…<2,0>,
    <2,1>…<n,0>…<n,1>…这(n+1)^2个有序对中存在多少个等差对?
        但是xym因为昨晚听他们班的女生唱歌太晚睡觉了,严重影响状态,现在他只能请求各位scau未来的希望帮助他解决这个问题。
    

    Input

    第一行输入一个整数T(T<=1000),表示case数。
    下面T行有T个case,每个case只有一个整数n(1<=n<=10^9),表示0<=x,y<=n;但是由于测试的时候发现用scanf("%lld",&n)有bug,所以为了修正这个bug,请各位用long long读入的同学在读入前先赋0给变量,
    例如 long long n=0; scanf("%lld",&n);
    

    Output

    每个case输出一行,表示等差对的数量,这个结果可能很大,只需最后结果%20111111即可。

    Sample Input

    2
    2
    100
    

    Sample Output

    5
    338350
    

    Hint

    注意不要让数据溢出,及时取模的处理

    Source

    by 201030720425

    Provider

    admin

     

    #include<stdio.h>
    int main()
    {
        long long n = 0, res = 0;
        long long a, b, c;
        int  T;
        scanf("%d", &T);
        while(T--)
        {
            res = 0;
            n = 0;
            scanf("%lld", &n);
            
            a = n, b = n + 1, c = 2 * n + 1;             
                if (a%2 == 0) a /= 2;              
                else b/=2;                        
                if (a%3 == 0) a /= 3;            
                else if (b%3 == 0) b /= 3;        
                else c /= 3;                     
        
            res = (((a*b)%20111111*c)%20111111 - ((n+2)*(n-1))/2 - 1)%20111111;
            res = (res + ((n+1)*n)/2)%20111111;
            printf("%lld\n", res%20111111);
        }
        return 0;
    }

    解题思路:

    Xo – Yo  = X1 – Y1  ->   Xo + Y1  =  X1 + Yo   即 : X0 + Y0 = X1 + Y1;

    所以可以转化成函数的形式 F = X + Y;

    输入一个数n ,(1<=n <= 10^9)

    令  n = X+Y;    比如我取 n = 5  则用坐标表示即为图中红色的线, X , Y 的取值有0,1,

    2, 3, 4 , 5

    线上共有6个点, 可以有C 6 取 2, 得到 6*5/2 = 15种可能

    同理,

    在 5 = X+Y 上有          C 5 取 2, 得到 5*4/2 = 10 种可能

    在 4 = X+Y 上有          C4 取 2, 得到 4*3/2 =  6 种可能

    ……

    ……

    累加有 (5*4 + 4*3 + 3*2 + 2*1)/2   +  6*5/2

    可以看到 以 6 =X+Y 为界限,上下方相同, 所以最终累加有:

    (5*4 + 4*3 + 3*2 + 2*1)/2 *2   +  6*5/2 

    (因为形成的都是正方形,所以没有上下不相等的可能)

    可以推出公式为: (输入n)

    n*(n-1) + (n-1)*(n-2) + …… + 2*1  + (n+1)*n/2  =

    n^2 – n + (n-1)^2 – (n-1) + …… + 2^2 – 2

    因为: 1^2 + 2^2 + 3^2 + 4^2 + …… + n^2  = n*(n+1)*(2n+1)/6

           2+3+4+5+ …… +n = (n+2)*(n-1)/2

    由此得出代码中的式子……

    //至于这里为什么能这样写,我的理解是: a和b中有一个是偶数,理所当然其一能被2整除
    //如果a,b不能被3整除,那么应该能够知道 三个连续的正整数中一定有一个能被3整除,
    //对于n(>=2)来说,n和n+1不能被3整除,那么n-1和n+1一定能被3整除,
    //而2*n+1 = n-1 + n+1, 所以a,b,c中一定有一个数能被3整除!
    //这也许就是n*(n+1)*(2n+1)%6 == 0 屹立不倒的原因吧。

    残余问题:

    公式的使用:(a*b)%c = ((a%c)*(b%c))%c

    运算规则:   

    模运算与基本四则运算有些相似,但是除法例外。其规则如下:   

    (a + b) % p = (a % p + b % p) % p (1)   

    (a - b) % p = (a % p - b % p) % p (2)   

    (a * b) % p = (a % p * b % p) % p (3)   

    ab % p = ((a % p)b) % p          

    (4)   

    结合律:

    ((a+b) % p + c) % p = (a + (b+c) % p) % p (5)   

    ((a*b) % p * c)% p = (a * (b*c) % p) % p  (6)    

    交换律:

    (a + b) % p = (b+a) % p   (7)   

    (a * b) % p = (b * a) % p (8)   

    分配律:

    ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (9)

  • 相关阅读:
    python中普通函数调用协程
    python骚操作之内建方法的使用
    Python常量类
    python实用技巧之任务切分
    容易被忽视的python装饰器的特性
    C语言学习笔记
    python mongo存在插入不存在更新,同时指定如果不存在才插入的字段
    python使用ThreadPoolExecutor每秒并发5个
    mac使用crawlab
    线性表的顺序存储结构
  • 原文地址:https://www.cnblogs.com/liaoguifa/p/2781724.html
Copyright © 2011-2022 走看看