zoukankan      html  css  js  c++  java
  • 出题的诀窍

    题目链接:https://ac.nowcoder.com/acm/contest/393/C

    链接:https://ac.nowcoder.com/acm/contest/393/C
    来源:牛客网

    题目描述

    给定m个长为n的序列a1,a2,,ama1,a2,…,am。

    小Z想问你:

    ni1=1ni2=1nim=1SUM(a1,i1,a2,i2,,am,im)  mod1000000007∑i1=1n∑i2=1n…∑im=1nSUM(a1,i1,a2,i2,…,am,im)  mod1000000007

    其中SUM()SUM(一个序列)表示这个序列中所有不同的数的和,相当于先sort,uniquesort,unique再求和。

    输入描述:

    第一行两个整数n,m。

    接下来m行,每行n个整数,第i行第j个表示ai,jai,j

    输出描述:

    一行一个整数,表示答案。
    示例1

    输入

    复制
    2 3
    1 2
    2 3
    1 3
    

    输出

    复制
    36

    说明

    一共有8种情况:

    SUM(1,2,1)=3SUM(1,2,3)=6SUM(1,3,1)=4SUM(1,3,3)=4SUM(1,2,1)=3SUM(1,2,3)=6SUM(1,3,1)=4SUM(1,3,3)=4

    SUM(2,2,1)=3SUM(2,2,3)=5SUM(2,3,1)=6SUM(2,3,3)=5SUM(2,2,1)=3SUM(2,2,3)=5SUM(2,3,1)=6SUM(2,3,3)=5

    把所有数字结果加起来就是36。

    备注:

    对于所有100%100%的数据,有1n,m2000,0ai,j109

    思路:这题打比赛的时候的确不会,范围太大了,看一眼就把深搜啊什么的否定了 。 2000^2000次方,计算机跑爆了都跑不出来,嗯。。。然后果断看下一题,但是又超时了。。。 是真的菜。
    嗯。。。 说思路: 这题仔细想想,可以想到其实就是算每个数出现了多少次,我在这里把它称为贡献度吧,所以就是每个数的贡献度之和,就是最后的答案了。
    那么具体是怎样的呢? 那么我们现在要解决的难题就是怎么快速得到一个数的贡献度。
    我们不妨这样想一下,如果题目没有要求去掉相同的数结果会是什么呢?? 显然就是每一个数乘以 N^(M-1) 次方 然后累加就是答案了。
    那么再进一步,去掉相同的数到底是去掉了多少次呢?
    对于第i行的数x,若它在前i-1行的数目分别为a1,a2......ai-1
    (n-a1)*(n-a2)*.....*(n-a(i-1))保证了前面不会出现相同的,n^(m-i)后面则不需要顾忌,因为就算选到了相同的,也只会把前面的数算进去
    累加所有情况就好了
    看懂了思路读者不妨先自己试着写一下,也许自己能写出来
    下面是AC代码:
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=1e7+50;
    const int mod=1000000007;
    typedef long long LL;
    struct Node
    {
        LL v,w;//存储对应的权值和所在的行
        bool  operator < (const Node x) const
        {
            return v==x.v?w<x.w:v<x.v;
        }
    
    
        public: Node(LL aa = 0,LL bb = 0)
        {
            v=aa;
            w=bb;
        }
    };
    Node a[maxn];
    LL sum[maxn];
    void Read(LL &n)
    {
        n=0;
        LL f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(f=='-') f=-f;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            n=(n<<1)+(n<<3)+(ch^48);
            ch=getchar();
        }
        n=n*f;
    }
    int main()
    {
        LL N,M;
        Read(N);
        Read(M);
    //    cout<<N<<" "<<M<<endl;
        int cnt=0;
        for(int i=0;i<M;i++)
        {
            for(int j=0;j<N;j++)
            {
                LL x;
                Read(x);
                a[cnt++]=Node{x,i};
            }
        }
        sort(a,a+cnt);
        sum[0]=1;
        for(int i=1;i<M;i++)//存N^i
        {
            sum[i]=sum[i-1]*N%mod;
        }
        int first=0;
        LL ans=0;
        for(int i=0;i<cnt;i++)//算每个数的贡献度
        {
            int x=1;//x存储第几行
            if(a[i].v!=a[i+1].v)//保证区间里的都是相等的
            {
                LL sum1=0;//存储有多少个
                LL sum2=1;//存储前面几行的数乘起来等于多少
                for(int j=first;j<i;j++)//采用记忆化的思想
                {
                    if(a[j].w==a[j+1].w) //找到一行里面有多少个与当前值相等的数
                    {
                        sum1++;
                    }
                    else
                    {
                        sum1++;
                        ans=(ans+(((sum2%mod)*sum1%mod)*sum[M-x]%mod)*a[i].v%mod)%mod;
                        sum2=(sum2%mod)*(N-sum1)%mod;
                        x++;
                        sum1=0;
    
                    }
                }
                if(a[i].w==a[i-1].w)
                {
                    sum1++;
                    ans=(ans+(((sum2%mod)*sum1%mod)*sum[M-x]%mod)*a[i].v%mod)%mod;
                }
                else
                {
                    ans=(ans+((sum2%mod)*a[i].v%mod)*sum[M-x]%mod)%mod;
                }
                first=i+1;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    在TreeView控件节点中显示图片
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1145 Hashing
    PAT 甲级 1145 Hashing
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1149 Dangerous Goods Packaging
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10574878.html
Copyright © 2011-2022 走看看