题目:
Desiderium
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 590 Accepted Submission(s): 227
Problem Description
There is a set of intervals, the size of this set is
n.
If we select a subset of this set with equal probability, how many the expected length of intervals' union of this subset is?
We assume that the length of empty set's union is 0, and we want the answer multiply2n modulo 109+7.
If we select a subset of this set with equal probability, how many the expected length of intervals' union of this subset is?
We assume that the length of empty set's union is 0, and we want the answer multiply2n modulo 109+7.
Input
The first line of the input is a integer
T,
meaning that there are T
test cases.
Every test cases begin with a integer n ,which is size of set.
Then n lines follow, each contain two integers l,r describing a interval of [l,r].
1≤n≤100,000.
−1,000,000,000≤l≤r≤1,000,000,000.
Every test cases begin with a integer n ,which is size of set.
Then n lines follow, each contain two integers l,r describing a interval of [l,r].
1≤n≤100,000.
−1,000,000,000≤l≤r≤1,000,000,000.
Output
For every test case output the answer multiply
2n
modulo 109+7.
Sample Input
2 1 0 1 2 0 2 1 3
Sample Output
1 7HintFor the second sample, the excepted length is $\frac{0+2+2+3}{4}=\frac{7}{4}$.
看到题目的第一时候我觉得是一题 dp,用dp[i]表示到i为止的集合的值,用一个标记来表示是否存在能重叠的集合;
时间复杂度可以用排序+线段树来优化,然后我发现因为x,y的范围过大,导致我开不出数组……
没思路了;
看了题解后发现用组合数来做;
把所有的集合化成一个个小的集合,统计每一个集合的重叠次数;
用重叠次数能计算出每个集合的使用次数;
使用次数乘上集合的宽度就是该集合能提供的值;
把所有的值加起来就是答案;
最让我无语的是,我好不容易从看每一题都是组合数的情况中走出来,没想到就遇到了组合数的题目;
组合数和dp在我的眼里真是傻傻分不清楚啊 orz……
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 1000000007
#define N 100007
#define LL __int64
using namespace std;
LL p[N];
struct node
{
LL x,y;
}data[N<<1];
LL sum[N];
int cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int T;
scanf("%d",&T);
p[0]=1;
for(int i=1;i<N;i++)
p[i]=(2*p[i-1] )%mod;
while(T--)
{
int n;
scanf("%d",&n);
int i,j;
for(i=1;i<=2*n;i+=2)
{
scanf("%I64d%I64d",&data[i].x,&data[i+1].x);
data[i].y=1;
data[i+1].y=-1;
}
sum[1]=p[n-1];
for(i=2;i<=n;i++)
sum[i]=(sum[i-1]+p[n-i])%mod;
sort(data+1,data+2*n+1,cmp);
LL ans=0;
LL num=0;
for(i=1;i<=2*n;i++)
{
num+=data[i].y;
ans=(ans+sum[num]*(data[i+1].x-data[i].x)%mod)%mod;
}
printf("%I64d\n",ans);
}
return 0;
}