• 看程序写结果(program)


    看程序写结果(program)


    Time Limit:1000ms Memory Limit:64MB


    题目描述


    LYK 最近在准备 NOIP2017 的初赛,它最不擅长的就是看程序写结果了,因此它拼命地
    在练习。
    这次它拿到这样的一个程序:


    Pascal:
    readln(n);
    for i:=1 to n do read(a[i]);
    for i:=1 to n do for j:=1 to n do for k:=1 to n do for l:=1 to n do
    if (a[i]=a[j]) and (a[i]<a[k]) and (a[k]=a[l]) then ans:=(ans+1) mod 1000000007;
    writeln(ans);


    C++:
    scanf(“%d”,&n);
    for (i=1; i<=n; i++) scanf(“%d”,&a[i]);
    for (i=1; i<=n; i++) for (j=1; j<=n; j++) for (k=1; k<=n; k++) for (l=1; l<=n; l++)
    if (a[i]==a[j] && a[i]<a[k] && a[k]==a[l]) ans=(ans+1)%1000000007;
    printf(“%d ”,ans);


    LYK 知道了所有输入数据,它想知道这个程序运行下来会输出多少。


    输入格式(program.in)


    第一行一个数 n,第二行 n 个数,表示 ai。


    输出格式(program.out)


    一个数表示答案。


    输入样例


    4
    1 1 3 3


    输出样例


    16


    数据范围


    对于 20%的数据 n<=50。
    对于 40%的数据 n<=200。
    对于 60%的数据 n<=2000。
    对于 100%的数据 n<=100000,1<=ai<=1000000000。
    其中均匀分布着 50%的数据不同的 ai 个数<=10,对于另外 50%的数据不同的 ai 个
    数>=n/10。

    思路:

      我们现在分析一下这个c++代码

    pcanf(“%d”,&n);
    for (i=1; i<=n; i++) scanf(“%d”,&a[i]);
    for (i=1; i<=n; i++) for (j=1; j<=n; j++) for (k=1; k<=n; k++) for (l=1; l<=n; l++)
    if (a[i]==a[j] && a[i]<a[k] && a[k]==a[l]) ans=(ans+1)%1000000007;
    printf(“%d
    ”,ans);

      这段代码里面有4重循环大概n==100就差不多爆时间

      所以我们要优化

      其中有两重循环可以简化为O(1);

      那就是第一重和最后一重

      就是询问有在这个数组里有几个和这个元素值相等的元素

      我们可以把所有的元素值记录下来

      然后离散化使之成为存储每个元素个数的数组

      然后每个数组的值都是这个元素个数的平方

      现在再看第二重和第三重循环

      这个是用来比较大小的

      于是

      我想到了前缀和

      就是把比当前元素个数的平方和记录下来

      然后每次取值就用前缀和就好

      经优化后成为一个O(n)时间复杂度的算法

      来,上代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    #define mod 1000000007LL
    
    using namespace std;
    
    long long int b[100001],n,ans;
    long long int sum[100001];
    
    int a[100001],head;
    
    char ch;
    
    void qread(long long int &x)
    {
        x=0;ch=getchar();
        while(ch>'9'||ch<'0') ch=getchar();
        while(ch<='9'&&ch>='0'){x=x*10+(int)(ch-'0');ch=getchar();}
    }
    
    int main()
    {
        qread(n);
        for(int i=1;i<=n;i++) qread(b[i]);
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)
        {
            if(b[i]!=b[i-1]) head++;
            a[head]++;
        }
        for(int i=1;i<=head;i++) a[i]=a[i]*a[i]%mod,sum[i]=(sum[i-1]+(a[i]%mod))%mod;
        for(int i=1;i<=head;i++) ans=(ans+((sum[i-1]*a[i])%mod))%mod;
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    保护【大数据】应用的步骤和工具
    提高UI设计效率的4个技巧
    你学会UI设计了吗?
    Android 零散知识点整理
    PHP面试和PHP开发者都应掌握的10个问题
    MySQL 中如何存储 emoji ?
    想在网上保持匿名?教你用Linux如何实现!
    数据库入门之运行原始 SQL 查找
    PHP之取得当前时间函数方法
    【在线】使用在线软件来完成任务
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6043931.html
Copyright © 2020-2023  润新知