AtCoder1983 [AGC001E] BBQ Hard

Posted yspm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder1983 [AGC001E] BBQ Hard相关的知识,希望对你有一定的参考价值。

一道比较好的组合题

Description

给定 (n) 个点对,求:

[sum^n_{i=1}sum^n_{j=i+1}inom {x_i+x_j+y_i+y_j}{x_i+x_j} ]

(nle 2 imes10^5 x_i,y_i le 2000)

Solution

暴力是不可能的对吧

我们发现一个 (inom{x+y}{x}) 的几何含义是从 ((0,0))((x,y)) 的路径条数

转化题意:

给定 (n) 个点 ((x_i,y_i)),每个点可以拆成 ((x_i,y_i))((-x_i,-y_i))

求在第三象限内找一个点,再在第一象限内找一个点的不同的路径数

我们首先可以对这个坐标进行 (dp) ,求从底下向上的路径(其实就是杨辉的那个求法)

(这里需要注意一下坐标为负的问题,如果开大数据范围可能是要离散吗?博主并不是很清楚)

最后统计答案,要减去相同点的情况,即 (inom {x_i+x_+y_i+y_i}{x_i+x_i}),然后除以 (2)

这里需要组合数

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
		while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
		return res*f;
	}
	const int mod=1e9+7,N=4e3+100,M=2e5+10,s=2010;
	int inv[M],fac[M];
	int n,x[M],y[M],f[N][N];
	inline void prework()
	{
		inv[0]=inv[1]=1; fac[0]=1;
		for(int i=1;i<M;++i) fac[i]=fac[i-1]*i%mod;
		for(int i=2;i<M;++i) inv[i]=mod-mod/i*inv[mod%i]%mod;
		for(int i=1;i<M;++i) inv[i]*=inv[i-1],inv[i]%=mod;;
		return ;
	}
	inline int C(int n,int m){return fac[n]*inv[n-m]%mod*inv[m]%mod; }
	
	signed main()
	{
		prework(); n=read(); 
		for(int i=1;i<=n;++i) x[i]=read(),y[i]=read(),f[s-x[i]][s-y[i]]++;
		for(int i=1;i<=(s<<1);++i)
		{
			for(int j=1;j<=(s<<1);++j)
			{
				f[i][j]+=(f[i][j-1]+f[i-1][j])%mod; f[i][j]%=mod;
			}
		}
		int ans=0;
		for(int i=1;i<=n;++i)
		{
			ans+=f[s+x[i]][s+y[i]]; ans%=mod;
			ans-=C((x[i]<<1)+(y[i]<<1),(x[i]<<1));
			ans+=mod; ans%=mod;
		}printf("%lld
",ans*inv[2]%mod);
		return 0;
	}
}
signed main(){return yspm::main();} 

Review

把不可求的组合数转化到几何上面,换成路径统计的那种做法来因值域降低复杂度

最后:逆元累乘的时候记得取模

以上是关于AtCoder1983 [AGC001E] BBQ Hard的主要内容,如果未能解决你的问题,请参考以下文章

[Agc001E] BBQ Hard

luogu AT1983 BBQ Hard

[AGC001 E]BBQ Hard

AGC.001E.BBQ Hard(组合 DP)

AGC001 E BBQ Hard

Atcoder AGC031B Reversi (DP计数)