【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=2751
【题意】
m个位置,已知每个位置的可能取值,问所有可能情况的每个位置的乘积的和。
【思路】
答案即为∏ΣAij,Aij为第i个位置的第j种取值。
前K中情况减去不可能的取值单独算sigma,后面的取值统一算为(((n+1)n)/2)^(m-K)。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long ll; 8 const int N =2e5+10; 9 const int mod = 1e9+7; 10 11 ll read() { 12 char c=getchar(); 13 ll f=1,x=0; 14 while(!isdigit(c)) { 15 if(c=='-') f=-1; c=getchar(); 16 } 17 while(isdigit(c)) 18 x=x*10+c-'0',c=getchar(); 19 return x*f; 20 } 21 22 struct Node { 23 int pos,val; 24 bool operator < (const Node& rhs) const{ 25 return pos<rhs.pos||(pos==rhs.pos&&val<rhs.val); 26 } 27 }a[N]; 28 29 int n,m,K; 30 31 ll pow(ll a,ll p,ll mod) 32 { 33 ll ans=1; 34 while(p) 35 { 36 if(p&1) ans=(ans*a)%mod; 37 a=(a*a)%mod; p>>=1; 38 } 39 return ans; 40 } 41 42 int main() 43 { 44 n=read(),m=read(),K=read(); 45 for(int i=1;i<=K;i++) 46 { 47 a[i].pos=read(), 48 a[i].val=read(); 49 } 50 sort(a+1,a+K+1); 51 ll ans=1,sum=(ll)n*(n+1)/2%mod,tmp=0,cnt=0; 52 for(int i=1;i<=K+1;i++) 53 { 54 if(i>1&&a[i].pos!=a[i-1].pos) 55 { 56 ans=ans*(sum-tmp+mod)%mod; 57 tmp=0; cnt++; 58 } 59 if(a[i].pos==a[i-1].pos&&a[i].val==a[i-1].val) continue; 60 tmp=(tmp+a[i].val)%mod; 61 } 62 ans=(ll)ans*pow(sum,m-cnt,mod)%mod; 63 printf("%lld ",ans); 64 return 0; 65 }