【分析】AGC012D Colorful Balls

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/82875664

分析:

有点水的分析题。

很显然,对每种颜色而言,其如果能和最小的交换,就一定能和所有能交换的交换。

因此,我们可以把所有 w i + w j x w_i+w_j\leq x (i,j同色),那么 w i = m i n ( w i , w j ) w_i=min(w_i,w_j)

这样搞完之后,再看看异色交换,也是一样的道理,它能和最小的换,就能和所有能换的换。另外,要注意最小颜色和它同色的情况(这种情况只能同色换)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 400010
#define MOD 1000000007
#define INF 0x3FFFFFFF
using namespace std;
typedef long long ll;
ll c[MAXN],w[MAXN],col[MAXN];
ll n,x,y,cnt;
vector<ll> a[MAXN];
ll fac[MAXN],ifac[MAXN];
ll fsp(ll d,ll t){
	ll res=1;
	while(t){
		if(t&1ll)
			res=res*d%MOD;
		d=d*d%MOD;
		t>>=1ll;	
	}
	return res;
}
int main(){
	SF("%lld%lld%lld",&n,&x,&y);
	ll mminw=INF;
	int minc;
	for(ll i=1;i<=n;i++){
		SF("%lld%lld",&c[i],&w[i]);
		a[c[i]].push_back(i);
		if(w[i]<mminw){
			mminw=w[i];
			minc=c[i];	
		}
	}
	ll mminw1=INF;
	for(ll i=1;i<=n;i++){
		ll minw=INF;
		for(ll j=0;j<ll(a[i].size());j++)	
			minw=min(minw,w[a[i][j]]);
		for(ll j=0;j<ll(a[i].size());j++)
			if(w[a[i][j]]+minw<=x)
				w[a[i][j]]=minw;
		if(minc!=i)
			mminw1=min(mminw1,minw);
	}
	for(ll i=1;i<=n;i++){
		if(c[i]==minc){
			if(w[i]+mminw1<=y){
				col[c[i]]++;
				cnt++;	
			}
		}
		else if(w[i]+mminw<=y){
			col[c[i]]++;
			cnt++;
		}
	}
	fac[0]=1;
	for(ll i=1;i<=cnt;i++)
		fac[i]=fac[i-1]*i%MOD;
	ifac[cnt]=fsp(fac[cnt],MOD-2);
	for(ll i=cnt;i>=1;i--)
		ifac[i-1]=ifac[i]*i%MOD;
	ll ans=fac[cnt];
	for(ll i=1;i<=n;i++)
		ans=ans*ifac[col[i]]%MOD;
	PF("%lld",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_34454069/article/details/82875664