codeforces 689E

来源:互联网 发布:网络维修工具包 编辑:程序博客网 时间:2024/06/02 09:34

题意:n个区间,找出任意k各区间重叠区间长度的和。

题解:从重叠部分考虑,原问题变成每个数字被多少组k区间包含。然后就是扫描区间,组合数计算。


#include<bits/stdc++.h>typedef long long LL;using namespace std;typedef pair<int,int> pii;#define MOD 1000000007LL powMod(LL x,LL p,LL mod){LL ret = 1;while(p){if(p&1){ret = ret*x%mod;}x = x*x%mod;p>>=1;}return ret;}int main(){ios_base::sync_with_stdio(0);int n,m;while(cin>>n>>m){vector<int> d1(n),d2(n),d;for(int i=0;i<n;i++){cin>>d1[i]>>d2[i];d.push_back(d1[i]);d.push_back(d2[i]);}sort(d1.begin(),d1.end());sort(d2.begin(),d2.end());sort(d.begin(),d.end());d.resize(unique(d.begin(),d.end())-d.begin());vector<LL> ss(n+1);ss[0]=1;for(int i=1;i<=n;i++){ss[i] = ss[i-1]*i%MOD;}LL ret = 0;int pc = 0;for(int i=0,j=0,k=0;k<(int)d.size();k++){if(k>=1){if(pc>=m&&d[k]-d[k-1]>1){//cout<<ss[pc]<<"/"<<ss[m]<<"/"<<ss[pc-m]<<endl;LL cnm = ss[pc]*powMod(ss[m]*ss[pc-m]%MOD,MOD-2,MOD)%MOD;ret = (ret + cnm*(d[k]-d[k-1]-1)%MOD)%MOD;//cout<<"C("<<pc<<","<<m<<"):"<<cnm<<endl;}}while(i<(int)d1.size()&&d1[i]<=d[k]){pc++;i++;}//cout<<"PC:"<<pc<<endl;if(pc>=m){LL cnm = ss[pc]*powMod(ss[m]*ss[pc-m]%MOD,MOD-2,MOD)%MOD;ret = (ret + cnm)%MOD;//cout<<"C("<<pc<<","<<m<<"):"<<cnm<<endl;}//cout<<"PC:"<<pc<<endl;while(j<(int)d2.size()&&d2[j]<=d[k]){pc--;j++;}}cout<<ret<<endl;}return 0;}


0 0
原创粉丝点击