看程序写结果(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\n”,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\n”,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;
}
时间: 2025-01-16 07:31:41

看程序写结果(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]

代码块练习题:看代码写程序的执行结果。

1 /* 2 代码块练习题: 3 看代码写程序的执行结果. 4 5 输出结果是: 6 林青霞都60了,我很伤心 7 我是main方法 8 Student 静态代码块 9 Student 构造代码块 10 Student 构造方法 11 Student 构造代码块 12 Student 构造方法 13 */ 14 15 class Student { 16 static { 17 System.out.println("Student 静态代码块"); 18 } 19 20 { 21 S

【C#学习笔记】【2】我的第一个程序My first program

是不是想到了你学C语言或者别的时候第一个程序“HelloWorld”?当然,我们也要从一个最简单的程序来了解程序最基本的组成——他就是My first program! 解决方案和项目 什么是解决方案和项目 假设有一个电子产品生产的工厂(你是不是想到了富士康),工厂有好几条生产流水线,第一条流水线生产苹果手机(当然是代工了!),第二条流水线生产三星手机(三星找别人代工么?),第三条生产什么,大家放开脑洞去想吧,嘿嘿.如果把工厂比作解决方案的话,那么每条生产流水线就是项目.也就是说,项目就是一个个

JAVA程序 写供别人调用的接口方法的时候 异常应该怎么处理?

要看出现的是哪种异常了.如果是使用某些定义好的函数,并且函数本身会产生异常处理方法一般两种:1.自己用try{}catch(){}语句捕获异常并处理.2.在定义接口的后面写上throw Exception.把异常抛出让使用接口的人处理异常.两种方法都可以.但如果是RuntimeException异常,那就是自己程序某些地方写错了,那你就必须找到并修改程序.JAVA程序 写供别人调用的接口方法的时候 异常应该怎么处理?,布布扣,bubuko.com

从扎克伯格捐450亿看程序员前景

内容简介 从扎克伯格捐450亿看程序员前景 前景是光明滴,努力是必要滴 之前朋友圈被Facebook的CEO扎克伯格捐款450亿美元的事情刷屏了. 大抵是说: 扎克伯格的中国太太为家里添了一个小公主.为了庆祝女儿的降生,扎克伯格与妻子普莉希拉·陈(Priscilla Chan)承诺将他们持有的Facebook 99%股份(按照Facebook当前股价计算,约450亿美元)捐出,给以自己及太太姓氏为合名的"ChanZuckerberg"基金会来推动慈善公 益事业,用以发展人类潜能和促进平

看别人写的优秀代码,是对自己的一种提高,看别人写的很恶心的代码,对自己也是一种提高:告诉自己不要这样写(转)

这两天,我做了两件事: 1.重构了系统某个模块的部分代码: 花了一天时间,一个6k多行的java文件,搞到4k行加若干个类文件,恕我能力有限,后面的实在重构不下去了,那是一种3个domain属性名几乎一样100多个字段但是却用同一个copy了三遍的方法来处理的欲哭无泪,那是一种使劲滚鼠标滚轮都滚不到一个方法尾部的绝望(100多个字段的几个类属性equals来,equals去,get来,set去的,这样类型的方法有那么五六个,你说能不多吗)...... 2.做了一个日志处理的小工具: 客户要求把日

程序写日志文件时该不该加锁

程序写日志文件时该不该加锁 日志(log) 为了让自己的思路更加清晰,下面我都会称日志为 log.因为日志这个词有两种含义,详情见百度百科释义或者维基百科释义. 日记的另一种说法.“志”字本身为“记录”的意思,日志就为每日的记录(通常是跟作者有关的). 服务器日志(server log),记录服务器等电脑设备或软件的运作. 我们这里说的当然是服务器日志,也就是  server log . 写入 log 一般写入 log 都会遵循以下步骤: int fd = open(path)write(fd,

第11周阅读程序写出执行结果1(5)

/* *Copyright (c) 2016,烟台大学计算机学院 *All rights reserved. *文件名称 : *作 者 : 刘云 *完成日期 : 2016年5月8号 *版 本 号 : v6.0 * *问题描述 : 阅读程序写出执行结果1(5) *输入描述 : 无 *程序输出 : */ /*********************************(a)****************************************************/ #include

使用 Java 程序写文件时,记得要 flush()

使用 Java 程序往磁盘写文件时碰到了这样的问题:文件写不全. 假如内容(StringBuffer/StringBuilder)有 100W 个字符,但是通过 Java 程序写到文件里的却不到 100W ,部分字符不见了. 代码大致是这样的: 1 private void writeToDisk() throws Exception { 2 File file = new File("FILE_PATH"); 3 OutputStreamWriter osw = null; 4 os