首页 > 代码库 > 看程序写结果
看程序写结果
看程序写结果(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;}
看程序写结果