[APIO2016]划艇

[APIO2016]划艇

思路:

参考这里

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
typedef long long int64;
const int N=501,mod=1e9+7;
int a[N],b[N],f[N],C[N],inv[N];
std::vector<int> v;
int main() {
	const int n=getint();
	inv[1]=1;
	for(register int i=2;i<=n;i++) {
		inv[i]=(int64)(mod-mod/i)*inv[mod%i]%mod;
	}
	for(register int i=1;i<=n;i++) {
		v.push_back(a[i]=getint());
		v.push_back(b[i]=getint()+1);
	}
	std::sort(v.begin(),v.end());
	v.resize(std::unique(v.begin(),v.end())-v.begin());
	const int m=v.size();
	for(register int i=1;i<=n;i++) {
		a[i]=std::lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
		b[i]=std::lower_bound(v.begin(),v.end(),b[i])-v.begin()+1;
	}
	f[0]=C[0]=1;
	for(register int i=1;i<m;i++) {
		const int len=v[i]-v[i-1];
		for(register int i=1;i<=n;i++) {
			C[i]=(int64)C[i-1]*inv[i]%mod*(len+i-1)%mod;
		}
		for(register int j=n;j>=1;j--) {
			if(a[j]>i||b[j]<=i) continue;
			for(register int k=j,cnt=0;k>=1;k--) {
				if(a[k]<=i&&b[k]>i) cnt++;
				(f[j]+=(int64)f[k-1]*C[cnt]%mod)%=mod;
			}
		}
	}
	int ans=0;
	for(register int i=1;i<=n;i++) (ans+=f[i])%=mod;
	printf("%d\n",ans);
	return 0;
}
posted @ 2018-08-18 16:14  skylee03  阅读(253)  评论(0编辑  收藏  举报