zoukankan      html  css  js  c++  java
  • 这是一个数学题牛客训练赛E

    题目描述   https://www.nowcoder.net/acm/contest/78/E

    已知有一个n+1个数的数列,对于给定的A0和An ,当i满足当1<=i<=n-1时有 
     
     
     
    现在小星想知道对于这个数列一段区间的和。
     

    输入描述:

    第一行输入四个数 n,A0,An,Q
    接下来Q行 每行输入两个数l,r
    0=< n,A0,An<=1e9,Q<=100000
    0<=l<=r<=n

    输出描述:

    对于每组查询输出Al到Ar的和
    示例1

    输入

    3 0 3 2
    1 1
    1 3

    输出

    1
    6

    备注:

    为了对萌新表现出友好,数据保证了对于Ai的每一项都是整数


    今天比赛遇上这个题,开始以为要用到组合数,而且数据比较大,可能会超时,一时间没有思路。
    比赛快结束时发现

    可以化简为 Ai=(a0*(n-i)+an*j)/n  把组合数消掉了,极大加快运算速度,将每项依次算出来再相加,
    于是匆匆写好了代码,提交后发现过了百分之20,后面的超时了,比赛结束了我还没找到原因

    翻看别人的代码,发现他没用用到累加,看样子有通式,突然我想到了等差数列的求和公式,Ai确实满足等差数列的通项,写好代码又发现没过
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <string>
    #include <cstring>
    using namespace std;
    int main()
    {
        int n,a0,an,q,m,n2;
       while(cin>>n>>a0>>an>>q)
       {
           for(int i=0;i<q;i++)
           {
               cin>>m>>n2;
               long long ans=((a0*(n-m)+an*m)/n+(a0*(n-n2)+an*n2)/n)*(n2-m+1)/2;
               cout<<ans<<endl;
           }
       }
        return 0;
    }
    View Code

    想了很久想到可能会爆掉数据,把那些an m l r不超过int范围的数据改成long long后就ac了,做个题真不容易

    虽然那些数据不会爆,但是它们在计算过程中会爆掉,比如 m和n都是int类型  m+n超过int范围的话会使m+n的结果出错

    做这道题真是不容易啊



  • 相关阅读:
    Debian 添加用户
    如何让安卓手机访问内网服务器?
    数据库权限
    CentOs
    批量导入sql文件。
    使用Navicat Premium连接mysql数据库
    git 合包
    linux 下文件打包
    git 分支管理
    gcc8.2安装
  • 原文地址:https://www.cnblogs.com/carcar/p/8428357.html
Copyright © 2011-2022 走看看