• 2015 Multi-University Training Contest 9 1005


    Arithmetic Sequence

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 779    Accepted Submission(s): 349


    Problem Description
    A sequence b1,b2,,bn are called (d1,d2)-arithmetic sequence if and only if there exist i(1in) such that for every j(1j<i),bj+1=bj+d1and for every j(ij<n),bj+1=bj+d2.

    Teacher Mai has a sequence a1,a2,,an. He wants to know how many intervals [l,r](1lrn) there are that al,al+1,,ar are (d1,d2)-arithmetic sequence.
     
    Input
    There are multiple test cases.

    For each test case, the first line contains three numbers n,d1,d2(1n105,|d1|,|d2|1000), the next line contains n integers a1,a2,,an(|ai|109).
     
    Output
    For each test case, print the answer.
     
    Sample Input
    5
    2 -2
    0 2 0 -2 0
    5 2
    3 2 3 3 3 3
     
    Sample Output
    12
    5
     
    Author
    xudyh
     
    Source
     
    题意:求在区间[1,N]中,[l,r]区间满足 l<=j<i && i<=j<r 中前半段为公差为d1的等差数列,后半段为d2的等差数列的区间个数。
    分析:

    首先预处理出来出 这个位置向前d1​​的等差序列和向后d22​​的等差数列能延续到多长,记作 l[i], r[i]

    如果d1≠d2,那么枚举中间位置,答案为l[i]*r[i]

    如果d1=d​​2,枚举开始位置,答案为ri

    其实我一开始也没看懂,不理解为什么单个数也能成为的区间也成立,后来无情打脸说离散没学好,说是数理逻辑中有当条件为假命题时,不论结果是真命题还是假命题,整个命题都是真命题,也算一个很牵强的解释吧= =

    d1!=d2,l[i]*r[i]可以说左边有l[i]个区间符合条件,右边有r[i]个区间符合条件,然后相乘得到组合起来有多少区间

    d1==d2,l[i]可以理解成 i 左边有多少符合条件的区间。

    #pragma comprint(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<string>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<map>
    #include<stdlib.h>
    #include<time.h>
    #include<algorithm>
    #define LL __int64
    #define FIN freopen("in.txt","r",stdin)
    using namespace std;
    const int MAXN=100000+5;
    int n,d1,d2;
    int l[MAXN],r[MAXN],a[MAXN];
    int main()
    {
        while(scanf("%d %d %d",&n,&d1,&d2)!=EOF)
        {
            for(int i=1;i<=n;i++) l[i]=r[i]=1;
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            for(int i=2;i<=n;i++)
                if(a[i]-a[i-1]==d1)
                    l[i]=l[i-1]+1;
            for(int i=n-1;i>=1;i--)
                if(a[i+1]-a[i]==d2)
                    r[i]=r[i+1]+1;
            LL ans=0;
            if(d1!=d2)
            {
                for(int i=1;i<=n;i++)
                    ans+=(LL)l[i]*r[i];
            }
            else
            {
                for(int i=1;i<=n;i++)
                    ans+=l[i];
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    使用C#调用C++类库
    C# IntPtr类型
    C# 调用C++ dll string类型返回
    C# try、catch、finally语句
    C语言 char *、char []、const char *、string的区别与相互转换
    C# 字符串string与char数组互转!
    C#如何调用C++(进阶篇)
    Springboot通过过滤器实现对请求头的修改
    【spring事务】
    命令行参数库:McMaster.Extensions.CommandLineUtils【转】
  • 原文地址:https://www.cnblogs.com/clliff/p/4743892.html
Copyright © 2020-2023  润新知