看代码写程序

看程序写结果(program) Time Limit:1000ms Memory Limit:64MB

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

c++:="" pcanf(“%d”,&n);

   ="" for="" (i="1;" i<="n;" i++)"

   =" scanf(“%d”,&a[i]);

   ="" (j="1;" j<="n;" j++)

    ="" (k="1;" k<="n;" k++)

    ="" (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)="" 一个数表示答案。=""

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

思路:

  一道简单的组合数类题目,因为样例错了耽误了点时间。

  求出对于某个数单个组合有多少种,然后把不同数的组合乘起来,加个前缀和优化就A了

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
long long ans,f[100005];
int i,n,a[100005],sum;
const int MOD=1000000007;
int main()
{
    freopen("program.in","r",stdin);
    freopen("program.out","w",stdout);
    scanf("%d",&n);
    for (i=1; i<=n; i++) scanf("%d",&a[i]);
    sort(a+1,a+n+1); sum=1;f[1]=1;
    for(int i=2;i<=n;i++)
    {
        f[i]=f[i-1];
        if(a[i]==a[i-1])
        {
            f[i]=(f[i]+2*sum+1)%MOD;
            sum++;
        }else
        {
            sum=1;
            f[i]++;
        }
    }
    sum=0;
    for(int i=n;i>=2;i--)
    {
        if(a[i+1]==a[i])    sum++;
        else sum=1;
        if(a[i]!=a[i-1])
            ans=(ans+f[i-1]*sum%MOD*sum)%MOD;
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2017-10-07 10:06  浪矢-CL  阅读(148)  评论(0编辑  收藏  举报