给定一个函数:

f([l,r]) = r - l + 1;

f(空集) = 0;

即f函数表示闭区间[l,r]的整点的个数

现在给出n个闭区间,和一个数k

从n个区间里面拿出k个区间,然后对这k个区间求并集,并求并集的f函数值

求所有C(n,k)种方案的f函数值之和

1 <= k <= n <= 200000

-10^9 <= l <= r <= 10^9

思路:

思路其实很容易想到

对这些区间缩点

g(i) 表示i这个点代表的区间的点数(即点i实际的点数)

s(i) 表示多少条线段含有i这个点

则:

ans = sigma(C(s[i],k) * g[i]) , 1 <= p <= tot

在缩点的时候使用优先队列,同时可以得到g,s这2个数组

代码:

  //File Name: cf689E.cpp
//Author: long
//Mail: 736726758@qq.com
//Created Time: 2016年07月11日 星期一 18时44分40秒 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <queue> #define LL long long using namespace std; const int MAXN = + ;
const int MAXN2 = + ;
const int MOD = (int)1e9 + ;
const int INF = 0x3f3f3f3f; struct Line{
int l,r;
bool operator<(const Line &a)const{
if(a.r == r) return a.l < l;
return a.r < r;
}
}line[MAXN]; int g[MAXN2],s[MAXN2];
LL jie[MAXN2]; void init(){
jie[] = ;
for(int i=;i<MAXN2;i++)
jie[i] = jie[i-] * i % MOD;
memset(g,,sizeof g);
memset(s,,sizeof s);
} LL qp(LL x,LL y){
LL res = ;
while(y){
if(y & ) res = res * x % MOD;
x = x * x % MOD;
y >>= ;
}
return res;
} LL get_C(int x,int y){
if(x < || x < y) return ;
if(y == || y == x) return ;
return jie[x] * qp(jie[y] * jie[x - y] % MOD,MOD - ) % MOD;
} bool cmp(Line x,Line y){
if(x.l == y.l)
return x.r < y.r;
return x.l < y.l;
} LL solve(int N,int K){
sort(line,line+N,cmp);
line[N].l = INF;
int tot = ,sum = ,now = line[].l;
int iter = ;
priority_queue<Line> que;
while(!que.empty()) que.pop();
while(!(iter == N && que.empty())){
while(iter < N && line[iter].l <= now){
que.push(line[iter]);
sum++;
iter++;
}
int now_r = que.top().r;
//printf("now_r = %d sum = %d iter = %d\n",now_r,sum,iter);
if(now_r < line[iter].l){
g[++tot] = now_r - now + ;
s[tot] = sum;
now = now_r + ;
//puts("1111111");
}
else{
g[++tot] = line[iter].l - now;
s[tot] = sum;
now = line[iter].l;
//puts("222222222222");
}
while(sum && que.top().r < now){
que.pop();
sum--;
}
if(que.empty())
now = line[iter].l;
}
LL ans = ;
for(int i=;i<=tot;i++){
ans = (ans + get_C(s[i],K) * g[i] % MOD) % MOD;
}
return ans;
} int main(){
init();
int n,k;
while(~scanf("%d %d",&n,&k)){
for(int i=;i<n;i++){
scanf("%d %d",&line[i].l,&line[i].r);
}
printf("%d\n",(int)solve(n,k));
}
return ;
}

最新文章

  1. SDWebImage源码解读 之 SDWebImageCompat
  2. python之网络编程
  3. [经验交流] 为 mesos framework 分配资源
  4. [刘阳Java]_斗胆介绍一下Eclipse快捷键大全[超详细]_第6讲
  5. Software Testing Lab1
  6. 生物信息大数据&amp;数据库(NCBI、EBI、UCSC、TCGA)
  7. 浅谈全区全服架构的SNS游戏后台
  8. Mahout推荐算法基础
  9. AM3359之U-boot及kernel编译
  10. IE6 png 透明--四种解决方法
  11. python中的文件
  12. [JavaScript] js 复制到剪切板
  13. asp.net微信开发第四篇----已关注用户管理
  14. mysql存储过程的权限 definer
  15. Using StructureMap DI and Generic Repository
  16. 防止UI穿透操作到游戏场景
  17. 『开源』设置系统 主音量(0~100 静音) VolumeHelper 兼容 Xp Win7 .Net 20 AnyCPU
  18. HTTP协议7之Cookie--转
  19. git 彻底删除历史记录中的大文件
  20. WebAPI实例--第一个API

热门文章

  1. mysql 存储过程简介
  2. guava学习--Ordering
  3. C#压缩文件夹
  4. 初学者SQL语句介绍
  5. Ubuntu下Speedtest的安装
  6. 在你决定从事iOS开发前需要清楚的几个问题
  7. JVM-并发-线程
  8. C语言之共用体
  9. pike实现
  10. CSS透明opacity和IE各版本透明度滤镜filter的最准确用法