hdu 5491 Desiderium(掃描線)

Desiderium

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 324    Accepted Submission(s): 130


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 multiply 2n 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].

1n100,000.

1,000,000,000lr1,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 7
Hint
For the second sample, the excepted length is $\frac{0+2+2+3}{4}=\frac{7}{4}$.
 

有一條數軸,還有一個區間的集合,集合大小爲nn。
現在等概率的從集合中選出集合的一個子集,求取出的子集的區間並集的期望長度。
空集的區間並長度被認爲是00

題解:掃描線的思想。


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>

using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=1e9+7;

struct node {
    int l,r;
} a[maxn];
int X[maxn],flag[maxn];
int n;

ll p[maxn];

void init() {
    p[0]=1;
    for(int i=1; i<maxn; i++)
        p[i]=p[i-1]*2%mod;
}
bool cmp(node a,node b) {
    return a.l<b.l||(a.l==b.l&&a.r<b.r);
}

int main() {
    int t;
    init();
    cin>>t;
    while(t--) {
        scanf("%d",&n);
        ll ans=0;
        ll sum=0;
        int m=0;
        for(int i=0; i<n; i++) {
            scanf("%d%d",&a[i].l,&a[i].r);
            //  sum=(sum+(ll)(a[i].r-a[i].l)*p[n-1]%mod)%mod;
            X[m++]=a[i].l;
            X[m++]=a[i].r;
        }
        sort(X,X+m);
        int k=0;
        X[k++]=X[0]; ///去重
        for(int j=1; j<m; j++)
            if(X[j-1]!=X[j])X[k++]=X[j];
        m=k;
        sort(a,a+n,cmp);
        int f=0;
        memset(flag,0,sizeof flag);
        for(int i=0; i<n; i++) {
            int lx=lower_bound(X,X+m,a[i].l)-X;
            int rx=lower_bound(X,X+m,a[i].r)-X;
            flag[lx]++;
            flag[rx]--;
        }
        for(int i=0; i<m-1; i++) {
            ll len=X[i+1]-X[i];
            f+=flag[i];
            sum=(sum+len*(p[n-f])%mod*(p[f]-1)%mod+2*mod)%mod;
        }
        printf("%I64d\n",sum);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章