首页 > 代码库 > 看程序写结果

看程序写结果

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

  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);

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

【输入格式】(program.in)

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

【输出格式】(program.out)

  一个数表示答案。

【输入样例】

  4

  1 1 3 3

【输出样例】

  4

【数据范围】

  对于20%的数据n<=50。

  对于40%的数据n<=200。

  对于60%的数据n<=2000。

  对于100%的数据n<=100000,1<=ai<=1000000000。

  其中均匀分布着50%的数据不同的ai个数<=10,对于另外50%的数据不同的ai个数>=n/10。

【题目分析】

  这个..你照着题目敲上去你就有40分了,然后你开心地去做下一题就好了hhh

  好吧我们看一下就会发现找到的四个数是满足“x x y y”这个形式的,而且x<y,我们把读入的a数组从小到大的排序,那所有相同的数字就会挨在一起了,这样我们会得到很多段数字,这些段也是从小到大的,因为他一个数字可以用多次,那每一个段中的数字的的组合方式就是len^2,然后把每一个段的组合数互相乘然后加和,但是考虑一下复杂度,如果直接相乘再相加的话会超时,那么用前缀和维护一下,搜索到一段数字的时候只需要和这段数字后面的相乘(因为后面的才大于这段数字),另外数据范围注意一下T_T

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int mo=1e9+7;const int maxn=1e6+10;int n;long long a[maxn],num[maxn],sum[maxn];long long ans;int x;int main(){    freopen("program.in","r",stdin);    freopen("program.out","w",stdout);    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%I64d",&a[i]);    sort(a+1,a+n+1);    for(int i=1;i<=n;i++)        num[i]=0;    for(int i=1;i<=n;i++)    {        if(a[i]!=a[i-1])            x++;        num[x]++;    }    for(int i=1;i<=x;i++)        num[i]=(num[i]*num[i])%mo;    for(int i=1;i<=x;i++)        sum[i]=sum[i-1]+num[i];    for(int i=1;i<x;i++)        ans=(ans+num[i]*(sum[x]-sum[i]))%mo;    cout<<ans;    fclose(stdin);fclose(stdout);    return 0;}

 

看程序写结果