• P2220 [HAOI2012]容易题


    看到这个题目名字总感觉它在嘲讽我做不出来

    题目描述:有m个数组成数列,数列中的每个数都在1~n范围内,求数列的每种情况内每个位置上的每个数乘起来的和。

    思路:我们可以先假设没有任何限制,那么我们的答案就是(n(n+1)/2)m,为什么那,下面给出计算过程(以n=2,m=3为例):

    由于本题带有限制,则我们可以先只处理没有限制的数位,之后再和带有限制的数相加就行了,即(n(n+1)/2)m-num(num为有限制的数的个数)再加上有限制的数算出的结果.

    还有就是注意要用快速幂优化,不然会超时,注意去重。另外,写取模时最好记得加括号,不然算式的计算方式可能会发生改变,失去取模意义。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<map>
     6 const int N=5e6+10;
     7 const int Mod=1000000007;
     8 typedef long long ll;
     9 using namespace std;
    10 ll num[N];
    11 map<ll,ll>cal;
    12 map<pair<ll,ll>,bool>mp;//去重 
    13 ll n,m,k;
    14 ll pow(ll a,ll t){//快速幂 
    15     a%=Mod;
    16     ll ans=1;
    17     while(t){
    18         if(t&1) ans=(ans*a)%Mod;
    19         t>>=1;
    20         a=(a*a)%Mod;
    21     }
    22     return ans;
    23 }
    24 int main(){
    25     scanf("%lld%lld%lld",&n,&m,&k);
    26     for(ll i=1;i<=k;++i){
    27         ll x,y;
    28         scanf("%lld%lld",&x,&y);
    29         if(!cal[x]) num[++num[0]]=x;
    30         if(mp[make_pair(x,y)]) continue;
    31         mp[make_pair(x,y)]=1;
    32         cal[x]+=y;//用于计算有限制的答案 
    33     }
    34     ll ans=1,sum=n*(n+1)/2;
    35     for(ll i=1;i<=num[0];++i){//计算有限制的答案
    36         ans=((ans%Mod)*((sum-cal[num[i]])%Mod))%Mod;
    37     }
    38     printf("%lld
    ",(ans%Mod*pow(sum,m-num[0])%Mod)%Mod);//加和 
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    补:冲刺Day1
    需求规格说明书2.0
    补:冲刺Day2
    冲刺Day3
    Base64上传图片
    C#怎样通过url调用接口
    js键盘控制DIV移动
    利用MVC的过滤器实现url的参数加密和解密
    在.net MVC中异步上传图片或者文件
    mvc url路由参数的加密和解密
  • 原文地址:https://www.cnblogs.com/li-jia-hao/p/12887979.html
Copyright © 2020-2023  润新知