题面传送门

题意:

给定 \(n\) 条线段,第 \(i\) 条线段左右端点分别为 \(l_i,r_i\)

定义一个线段集合的复杂度为其形成的连通块的个数的 \(k\) 次方。

求这 \(n\) 条线段所有子集的复杂度之和。

答案对 \(10^9+7\) 取模。

\(1\leq n\leq 10^5\),\(1\leq k\leq 10\)

将所有线段按左端点从小到大排序,然后依次加入这 \(n\) 个线段。

先考虑 \(k=1\) 的情形,定义 \(f_r\) 为当前右端点最大的线段的右端点为 \(r\) 的所有集合的所形成的连通块之和。

当我们加入一条线段 \([l,r]\) 时,分三种情况:

  1. 对于右端点 \(\leq l-1\) 的集合,加入这条线段后复杂度会 \(+1\),右端点变为 \(r\),故将 \(f_1+1,f_2+1,\dots,f_{l-1}+1\)到 $ f_r$ 中。
  2. 对于右端点在 \(l\) 和 \(r\) 之间的集合,加入这条线段后复杂度不变,右端点变为 \(r\),故将 \(f_l,f_{l+1},\dots,f_r\) 累加到 \(f_r\) 中。
  3. 对于右端点 \(>r\) 的集合。加入这条线段后复杂度也不变,右端点也不变,故令所有 \(f_i(i>r)\) 乘 \(2\)。

最终答案即为所有 \(f_i\) 的和。

接下来考虑 \(k\) 不为 \(1\) 的情况。其实与 \(k=1\) 大差不差,只不过我们在情况 \(1\) 中,我们要支持维护 \((f_1+1)^k,(f_2+1)^k,\dots,(f_{l-1}+1)^k\) 的和。

这玩意儿可以用二项式定理展开为 \(\sum\limits_{i=1}^{l-1}\dbinom{k}{0}f_i^0+\dbinom{k}{1}f_i^1+\dbinom{k}{2}f_i^2+\dots+\dbinom{k}{k}f_i^k=\sum\limits_{j=0}^k\dbinom{k}{j}\sum\limits_{i=1}^{l-1}f_i^j\)。

建立 \(k+1\) 棵线段树,第 \(j\) 棵的下标 \(i\) 位置维护 \(f_i^j\),支持区间加,区间乘 \(2\),区间求和。

时间复杂度 \(\mathcal O(nk\log n)\)

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
template<typename T> void read(T &x){
char c=getchar();T neg=1;
while(!isdigit(c)){if(c=='-') neg=-1;c=getchar();}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=neg;
}
const int MAXN=1e5;
const int MAXK=10;
const int MOD=1e9+7;
int n,m;pii p[MAXN+5];
struct segtree{
struct node{
int l,r,val,lz;
} s[MAXN*8+5];
void build(int k,int l,int r){
s[k].l=l;s[k].r=r;s[k].lz=1;if(l==r) return;
int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
void update(int k){s[k].val=(s[k<<1].val+s[k<<1|1].val)%MOD;}
void pushdown(int k){
if(s[k].lz!=1){
s[k<<1].val=1ll*s[k<<1].val*s[k].lz%MOD;
s[k<<1|1].val=1ll*s[k<<1|1].val*s[k].lz%MOD;
s[k<<1].lz=1ll*s[k<<1].lz*s[k].lz%MOD;
s[k<<1|1].lz=1ll*s[k<<1|1].lz*s[k].lz%MOD;
s[k].lz=1;
}
}
void mul(int k,int l,int r,int x){
if(l>r) return;
if(l<=s[k].l&&s[k].r<=r){
s[k].val=2ll*s[k].val%MOD;
s[k].lz=2ll*s[k].lz%MOD;return;
} pushdown(k);int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) mul(k<<1,l,r,x);
else if(l>mid) mul(k<<1|1,l,r,x);
else mul(k<<1,l,mid,x),mul(k<<1|1,mid+1,r,x);
update(k);
}
void add(int k,int p,int x){
if(s[k].l==s[k].r){s[k].val=(s[k].val+x)%MOD;return;}
pushdown(k);int mid=(s[k].l+s[k].r)>>1;
if(p<=mid) add(k<<1,p,x);else add(k<<1|1,p,x);
update(k);
}
int query(int k,int l,int r){
if(l>r) return 0;if(l<=s[k].l&&s[k].r<=r) return s[k].val;
pushdown(k);int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) return query(k<<1,l,r);else if(l>mid) return query(k<<1|1,l,r);
else return (query(k<<1,l,mid)+query(k<<1|1,mid+1,r))%MOD;
}
} t[MAXK+2];
int x[MAXK+2];
int c[MAXK+2][MAXK+2];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&p[i].fi,&p[i].se);
for(int i=0;i<=MAXK;i++){
c[i][0]=1;for(int j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
}
sort(p+1,p+n+1);
for(int i=0;i<=m;i++) t[i].build(1,0,2*n);
t[0].add(1,0,1);
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
int val=t[j].query(1,p[i].fi,p[i].se);
t[j].add(1,p[i].se,val);//condition 2
}
for(int j=0;j<=m;j++) x[j]=t[j].query(1,0,p[i].fi-1);
for(int j=0;j<=m;j++){
int val=0;
for(int k=0;k<=j;k++) val=(val+1ll*x[k]*c[j][k]%MOD)%MOD;
t[j].add(1,p[i].se,val);//condition 1
}
for(int j=0;j<=m;j++) t[j].mul(1,p[i].se+1,2*n,2);//condition 3
}
printf("%d\n",t[m].query(1,0,2*n));
return 0;
}

洛谷 P6144 - [USACO20FEB]Help Yourself P(二项式定理+线段树)的更多相关文章

  1. 洛谷P2982 [USACO10FEB]慢下来Slowing down(线段树 DFS序 区间增减 单点查询)

    To 洛谷.2982 慢下来Slowing down 题目描述 Every day each of Farmer John's N (1 <= N <= 100,000) cows con ...

  2. Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)

    题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...

  3. 洛谷 P1083 借教室【二分+差分/线段树】

    二分mid,然后用1~mid的操作在差分序列上加减,最后把差分序列前缀和起来,看是否有有超过初始r值的 #include<iostream> #include<cstdio> ...

  4. 【洛谷4219】[BJOI2014]大融合(线段树分治)

    题目: 洛谷4219 分析: 很明显,查询的是删掉某条边后两端点所在连通块大小的乘积. 有加边和删边,想到LCT.但是我不会用LCT查连通块大小啊.果断弃了 有加边和删边,还跟连通性有关,于是开始yy ...

  5. 洛谷P4577 [FJOI2018]领导集团问题(dp 线段树合并)

    题意 题目链接 Sol 首先不难想到一个dp,设\(f[i][j]\)表示\(i\)的子树内选择的最小值至少为\(j\)的最大个数 转移的时候维护一个后缀\(mx\)然后直接加 因为后缀max是单调不 ...

  6. 洛谷P2178 [NOI2015]品酒大会(后缀自动机 线段树)

    题意 题目链接 Sol 说一个后缀自动机+线段树的无脑做法 首先建出SAM,然后对parent树进行dp,维护最大次大值,最小次小值 显然一个串能更新答案的区间是\([len_{fa_{x}} + 1 ...

  7. 洛谷.3437.[POI2006]TET-Tetris 3D(二维线段树)

    题目链接 下落一个d*s的方块,则要在这个平面区域找一个最高的h' 更新整个平面区域的值为h+h' 对于本题,维护最大高度h和all 对于平面的x轴维护一棵线段树t1,每个t1的节点维护对应y轴的两棵 ...

  8. 洛谷P3586 [POI2015]LOG(贪心 权值线段树)

    题意 题目链接 Sol 显然整个序列的形态对询问没什么影响 设权值\(>=s\)的有\(k\)个. 我们可以让这些数每次都被选择 那么剩下的数,假设值为\(a_i\)次,则可以\(a_i\)次被 ...

  9. 2018.08.11 洛谷P3224 [HNOI2012]永无乡(线段树合并)

    传送门 给出n个带点权的点,支持连边和查询连通块第k大. 这个貌似就是一道线段树合并的裸板啊... 代码: #include<bits/stdc++.h> #define N 100005 ...

随机推荐

  1. 【Java虚拟机10】ClassLoader.getSystemClassLoader()流程简析

    前言 学习类加载必然离开不了sun.misc.Launcher这个类和Class.forName()这个方法. 分析ClassLoader.getSystemClassLoader()这个流程可以明白 ...

  2. [对对子队]会议记录4.10(Scrum Meeting 1)

    本次每日例会的开会时间是4月10日晚上20:00,使用腾讯会议作为开会工具. 今天已完成的工作 何瑞 ​ 工作内容:制作UI界面的指令编辑系统,已大致实现指令的衔接 ​ 相关issue:实现用户指令编 ...

  3. [技术博客] 通过ItemTouchHelper实现侧滑删除功能

    通过ItemTouchHelper实现侧滑删除功能 一.效果 二.具体实现 demo中演示的这种左滑删除的效果在手机APP中比较常用,安卓也为我们提供了专门的辅助类ItemTouchHelper来帮助 ...

  4. 嵌入式大佬给你分析stm32串口

    stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...

  5. 零基础学习C语言字符串操作总结大全

    本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, ...

  6. 21.10.18 test

    可可大神出题,四款有趣的游戏推荐,第四个好玩/se T1 loopers \(\color{green}{100}\) 考虑钦定 \(a_1,a_i\) 的位置,固定左边一坨,那么剩下的一坨的 \(\ ...

  7. 【java+selenium3】模态框处理(五)

    一.模态框的定义: 模态对话框(Modal Dialogue Box , 又叫做模式对话框),是指在用户想要对话框以外的应用程序进行操作时候,必须先对该对话框进行响应.如单击[确定]或者[返回]按钮等 ...

  8. 【java+selenium3】元素的扩展操作(二)

    1.判断当前元素是否可显示 isDisplay(); //判断元素是否可见 boolean a= driver.findElement(By.id("xxx")).isDispla ...

  9. MySQL:由于找不到VCRUNTIME140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题

    我只是搬用工,记录一下 方法一: 安装这个微软常用运行库合集(https://www.repaik.com/), 链接:https://pan.baidu.com/s/1r4JJaUKjw-y1g3l ...

  10. 聊聊sql优化的15个小技巧

    前言 sql优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到. 如果某天你负责的某个线上接口,出现了性能问题,需要做优化.那么你首先想到的很有可能是优化sql语句,因为它 ...