CF101B Buses

题目链接

题意分析

计数问题跑DP 这是常识原谅我第一时间没有想出来

我们用dp[i]表示搭乘第i辆车下车的方案数

最终的答案 就是把所有终点站ti=n的车下车的方案数累加

现在考虑怎么转移

我们先把所有车按照终点站排序

对于第i辆车 查找哪些车会停在[si,ti-1] 将这些车的方案累加到dp[i]上

用于终点站是单调的 所以我们可以使用二分确定

由于有贡献的车必然是一段连续的区间 所以我们通过前缀和优化累加

CODE:

#include<bits/stdc++.h>
#define N 300080
#define mod 1000000007
using namespace std;
int n,m;
struct Node
{
	int s,t;
	friend bool operator <(const Node &A,const Node &B)
	{return A.t<B.t;}
}e[N];
long long dp[N],sum[N];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i) scanf("%d%d",&e[i].s,&e[i].t);
	sort(e+1,e+m+1);
	for(int i=1;i<=m;++i) if(e[i].s==0) dp[i]=1LL;
	for(int i=1;i<=m;++i)
	{
		int le=1,ri=i-1,tmp1=0,tmp2=0;
		while(le<=ri)
		{
			int mid=(le+ri)>>1;
			if(e[mid].t>=e[i].s) {tmp1=mid;ri=mid-1;}
			else le=mid+1;
		}
		le=1;ri=i-1;
		while(le<=ri)
		{
			int mid=(le+ri)>>1;
			if(e[mid].t<e[i].t) {tmp2=mid;le=mid+1;}
			else ri=mid-1;
		}
		if(tmp1!=0&&tmp2!=0) dp[i]=(dp[i]+(sum[tmp2]-sum[tmp1-1])%mod+mod)%mod;
		sum[i]=(sum[i-1]+dp[i])%mod; 
	}
	long long tmp=0;
	for(int i=1;i<=m;++i) if(e[i].t==n) tmp=(tmp+dp[i]+mod)%mod;
	printf("%lld\n",tmp); 
	return 0;
} 
posted @ 2021-02-07 22:16  tcswuzb  阅读(52)  评论(0编辑  收藏  举报