zoukankan      html  css  js  c++  java
  • [HAOI2012] 容易题

    题目

    首先,原题题目就叫这个,不是我讽刺这个题简单……
    原题地址

    解说

    咱们先假设我一个限制都没有,那么每个数都可以取(1~n)之间的任何一个整数,在自己的脑海里提一遍公因数就会发现这时答案为((1+2+ dots +n)^m),再用上求和公式变为((frac{n(n+1)}{2})^m)
    那么现在我们加上限制条件,每加上一个限制就少一个选择,那么我们就把这个限制数从这个乘数里剔除即可,即原来是(1+2+ dots +n),现在变为(1+2+ dots +n-limit1-limit2 dots),也就是((frac{n(n+1)}{2})^m-limit1-limit2 dots)。而没有受到限制的数照乘不误,即若有(js)个有限制的数那么这些没限制的数乘起来就是((frac{n(n+1)}{2})^{m-js})。最后结果把有限制的没限制的乘一起即可。
    几点提醒:
    1.数太大了,能取模的地方都取模。
    2.用快速幂优化。
    3.样例就能看出来可能有重复限制,记得去重。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1000000007;
    const int maxn=1e5+3;
    map<pair<ll,ll>,bool> inf;
    map<ll,ll> sum;
    ll n,m,k,js,num[maxn];
    ll power(ll a,ll x){
    	a%=mod;
    	ll ans=1;
    	for(;x;x>>=1,a=a*a%mod){
    		if(x&1) ans=ans*a%mod;
    	}
    	return ans%mod;
    }
    ll read(){
       ll s=0,w=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
       return s*w;
    } 
    int main(){
    	n=read(); m=read(); k=read();
    	while(k--){
    		ll x,y;
    		x=read(); y=read();
    		if(!sum[x]) num[++js]=x;
    		if(inf[make_pair(x,y)]) continue;
    		inf[make_pair(x,y)]=1;
    		sum[x]+=y;
    	}
    	ll ans=1,Max=(n+1)*n/2;
    	for(ll i=1;i<=js;i++){
    		ans*=(Max-sum[num[i]])%mod;
    		ans%=mod;
    	}
    	printf("%lld",ans%mod*power(Max,m-js)%mod%mod);
    	return 0;
    }
    

    幸甚至哉,歌以咏志。

  • 相关阅读:
    构建布局良好的Windows程序
    新认知之WinForm窗体程序
    分组查询之牛刀小试!
    Azure虚拟机时间同步问题
    关闭同一网络内的windows主机
    关于jdbc和数据库连接池的关系(不是封装的关系)
    spring,springMVC的优点和区别
    从新向你学习javase(第一天)
    spring包
    事物
  • 原文地址:https://www.cnblogs.com/DarthVictor/p/12885235.html
Copyright © 2011-2022 走看看