其他分享
首页 > 其他分享> > [USACO20FEB]Help Yourself G

[USACO20FEB]Help Yourself G

作者:互联网

LXXV.[USACO20FEB]Help Yourself G

思路:

考虑将线段按照左端点排序。

设\(f[i]\)表示前\(i\)个线段的复杂度之和。

则\(f[i]=2*f[i-1]+2^{sum[l_i-1]}\)。其中\(sum_i\)是右端点\(\leq i\)的线段数目,\(l_i\)是\(i\)线段的左端点。

思考:

再往前的复杂度之和,无论第\(i\)根线段选与不选,都是无法改变的。因此要\(*2\)。

当之前的线段与线段\(i\)交集为空时,联通块新增一块。这部分共有\(2^{sum[l_i-1]}\)种选法。

复杂度\(O(n\log n)\)(排序是瓶颈,如果换成桶排就是\(O(n)\)的)

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,sum[200100],bin[100100],f[100100];
pair<int,int>p[100100];
int main(){
	scanf("%d",&n),bin[0]=1;
	for(int i=1;i<=n;i++)scanf("%d%d",&p[i].first,&p[i].second),sum[p[i].second]++,bin[i]=(bin[i-1]<<1)%mod;
	for(int i=1;i<=2*n;i++)sum[i]+=sum[i-1];
	sort(p+1,p+n+1);
	for(int i=1;i<=n;i++)f[i]=(2ll*f[i-1]+bin[sum[p[i].first-1]])%mod;
	printf("%d\n",f[n]);
	return 0;
}

标签:Help,int,sum,100100,Yourself,复杂度,端点,线段,USACO20FEB
来源: https://www.cnblogs.com/Troverld/p/14598412.html